コード例 #1
0
def doInsert_SwayLinesSurfaces(lc_includedSwayLinesFC, includedSwaySurfacesFC,  lc_listOfSpans):
    try:

        # Delete and Insert features into 4 tables.
        fieldListBothLinesAndPoints = ['SHAPE@', 'FromTower', 'ToTower', 'LineNumber']
        deleteFieldList = ["FromTower", "ToTower", "LineNumber"]

        newRow = utils.NewRow()
        newRow.setFieldNames(fieldListBothLinesAndPoints)

        for span in lc_listOfSpans:
            fromTower = span.fromTower
            toTower = span.toTower
            lineNumber = span.lineNumber
            deleteWhereClause = "FromTower = " + str(fromTower) + " and ToTower = " + \
                                str(toTower) + " and LineNumber = " + str(lineNumber)
            # All new rows have these fields/values.
            newRow.set('FromTower', fromTower)
            newRow.set('ToTower', toTower)
            newRow.set('LineNumber', lineNumber)

            ####################################

            # Insert new sway lines.
            cursorInsertLine = arcpy.da.InsertCursor(lc_includedSwayLinesFC, newRow.getFieldNamesList())
            for swayLine in span.swayLines:
                lineShape = vg.funPolylineToArcpyPolyline([swayLine])
                newRow.set('SHAPE@', lineShape)
                cursorInsertLine.insertRow(newRow.getFieldValuesList())

            del cursorInsertLine

            # Insert new sway surface panels.
            cursorInsertPolygon = arcpy.da.InsertCursor(includedSwaySurfacesFC, newRow.getFieldNamesList())
            for panel in span.surfacePanels:
                polygonShape = vg.funPolygonToArcpyPolygon([panel])
                newRow.set('SHAPE@', polygonShape)
                cursorInsertPolygon.insertRow(newRow.getFieldValuesList())
            del cursorInsertPolygon

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #2
0
def makeSurfacePanels(span):
    surfacePanels = []
    swaysLines = span.swayLines
    swayLineCount = len(swaysLines)
    for swayIndex in range(0, swayLineCount - 1):
        thisSway = swaysLines[swayIndex]
        nextSway = swaysLines[swayIndex + 1]
        thisSwayNodes = thisSway.nodes
        nextSwayNodes = nextSway.nodes

        nodeCount = len(thisSwayNodes)
        lastNextNodeIndex = nodeCount - 2
        for nodeIndex in range(0, nodeCount - 1):
            thisSway_thisNode = thisSwayNodes[nodeIndex]
            thisSway_nextNode = thisSwayNodes[nodeIndex + 1]
            nextSway_thisNode = nextSwayNodes[nodeIndex]
            nextSway_nextNode = nextSwayNodes[nodeIndex + 1]
            if nodeIndex == 0:
                n0 = thisSway_thisNode
                # no n1 as this is triangle.
                n2 = nextSway_nextNode
                n3 = thisSway_nextNode
                panel = vg.Polygon([n0, n2, n3])
            elif nodeIndex == lastNextNodeIndex:
                n0 = thisSway_thisNode
                n1 = nextSway_thisNode
                n2 = nextSway_nextNode
                # no n3 as this is triangle.
                panel = vg.Polygon([n0, n1, n2])
            else:
                n0 = thisSway_thisNode
                n1 = nextSway_thisNode
                n2 = nextSway_nextNode
                n3 = thisSway_nextNode
                panel = vg.Polygon([n0, n1, n2, n3])

            surfacePanels.append(panel)
        # END FOR nodeIndex
    # END FOR swayIndex
    span.surfacePanels = surfacePanels
    pass
コード例 #3
0
def InsertTowerBasePoints(towerBasePoints, tower_configuration, lc_tower_placement_points, lc_fields):
    for index in range(0, len(towerBasePoints)):
        towerBasePoint = towerBasePoints[index]
        arcpyPoint = vg.funPointToArcpyPoint(towerBasePoint.point)
        newRow = utils.NewRow()

        newRow.set('SHAPE@', arcpyPoint)
        newRow.set('Cardinal_Direction', towerBasePoint.cardinalDirection)
        newRow.set('TowerNumber', towerBasePoint.towerNumber)
        towerConfigIndex = 2
        for k, v in vars(tower_configuration).items():
            newRow.set(lc_fields[towerConfigIndex], v)
            towerConfigIndex += 1
        # Gert I did this after that loop, because I needed to update the value of these keys maximum_sag_allowance, and structure_type
        # and those values are being set on tower base points now (not tower config), but lc_fields has those keys already.
        newRow.set('maximum_sag_allowance', towerBasePoint.maximum_sag_allowance)
        newRow.set('structure_type', towerBasePoint.structure_type)

        ####################################
        # Insert
        cursorInsert = arcpy.da.InsertCursor(lc_tower_placement_points, newRow.getFieldNamesList())
        cursorInsert.insertRow(newRow.getFieldValuesList())
        del cursorInsert
        pass
コード例 #4
0
def doSpanRemoveAndInsert(lc_includedTransmissionLinesFC, lc_includedTransmissionLineGuides, lc_listOfSpans):
    try:
        # Delete and Insert features into 4 tables.
        fieldListSpans = ['SHAPE@', 'FromTower', 'ToTower', 'LineNumber', 'SagDistance', 'HorizontalTension', 'LineLength', 'WeightPerUnitLength']
        fieldListGuideLines = ['SHAPE@', 'FromTower', 'ToTower', 'LineNumber', 'FromX', 'FromY', 'FromZ', 'ToX', 'ToY', 'ToZ', 'SagDistance', 'WeightPerUnitLength']
        deleteFieldList = ["FromTower", "ToTower", "LineNumber"]

        newRow = utils.NewRow()
        newRow.setFieldNames(fieldListSpans)

        for span in lc_listOfSpans:
            fromTower = span.fromTower
            toTower = span.toTower
            lineNumber = span.lineNumber
            deleteWhereClause = "FromTower = " + str(fromTower) + " and ToTower = " + \
                                str(toTower) + " and LineNumber = " + str(lineNumber)
            # All new rows have these fields/values.
            newRow.set('FromTower', fromTower)
            newRow.set('ToTower', toTower)
            newRow.set('LineNumber', lineNumber)

            # Delete existing TransmissionLines.
            deleteCursor = arcpy.da.UpdateCursor(lc_includedTransmissionLinesFC, deleteFieldList, deleteWhereClause)
            for row in deleteCursor:
                deleteCursor.deleteRow()
            if deleteCursor:
                del deleteCursor

            # Delete existing LineGuides.
            deleteCursor = arcpy.da.UpdateCursor(lc_includedTransmissionLineGuides, deleteFieldList, deleteWhereClause)
            for row in deleteCursor:
                deleteCursor.deleteRow()
            if deleteCursor:
                del deleteCursor

            ####################################

            # Insert new transmisson line.
            cursorInsertLine = arcpy.da.InsertCursor(lc_includedTransmissionLinesFC, newRow.getFieldNamesList())
            lineShape = vg.funPolylineToArcpyPolyline([span.polyline])
            newRow.set('SHAPE@', lineShape)
            newRow.set('FromTower', span.fromTower)
            newRow.set('ToTower', span.toTower)
            newRow.set('LineNumber', span.lineNumber)
            # XX Added extra reporting fields here:
            newRow.set('SagDistance', span.sagDistance)
            newRow.set('HorizontalTension', span.horizontalTension)
            newRow.set('LineLength', span.lineLength)
            newRow.set('WeightPerUnitLength', span.weightPerUnitLength)

            cursorInsertLine.insertRow(newRow.getFieldValuesList())
            del cursorInsertLine

            # Insert new lineGuide.
            newRowGuideLines = utils.NewRow()

            fromX = span.fromPoint.x
            fromY = span.fromPoint.y
            fromZ = span.fromPoint.z

            toX = span.toPoint.x
            toY = span.toPoint.y
            toZ = span.toPoint.z

            newRowGuideLines.setFieldNames(fieldListGuideLines)
            cursorInsertLineGuide = arcpy.da.InsertCursor(lc_includedTransmissionLineGuides, newRowGuideLines.getFieldNamesList())
            polylineShape = vg.funPolylineToArcpyPolyline([span.lineGuide])
            newRowGuideLines.set('SHAPE@', polylineShape)
            newRowGuideLines.set('FromTower', fromTower)
            newRowGuideLines.set('ToTower', toTower)
            newRowGuideLines.set('LineNumber', lineNumber)
            newRowGuideLines.set('FromX', fromX)
            newRowGuideLines.set('FromY', fromY)
            newRowGuideLines.set('FromZ', fromZ)
            newRowGuideLines.set('ToX', toX)
            newRowGuideLines.set('ToY', toY)
            newRowGuideLines.set('ToZ', toZ)
            newRowGuideLines.set('SagDistance', span.sagDistance)
            newRowGuideLines.set('WeightPerUnitLength', span.weightPerUnitLength)
            cursorInsertLineGuide.insertRow(newRowGuideLines.getFieldValuesList())
            del cursorInsertLineGuide

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #5
0
def adjustSpans(lc_scratch_ws, lc_catenary, lc_guide_lines, lc_adjust_all, lc_debug, lc_use_in_memory):
    try:
        # First, find the from and to points, and line number for this guide line.
        fieldList = ["FromTower", "ToTower", "LineNumber", "FromX", "FromY", "FromZ", "ToX", "ToY", "ToZ", "SagDistance", "WeightPerUnitLength"]
        fieldAccess = utils.FieldAccess(fieldList)

        # lc_guide_lines can be a layer. There is only 1 feature (selected)
        cursor = arcpy.da.SearchCursor(lc_guide_lines, fieldList)
        # Process selected guidelines.
        # XX Pretend for now that only one guideline is selected.
        index = 0
        for row in cursor:
            # only one guideline is selected.
            if index == 0:
                fieldAccess.setRow(row)
                lineNumber = fieldAccess.getValue("LineNumber")
                fromTower = fieldAccess.getValue("FromTower")
                toTower = fieldAccess.getValue("ToTower")
                fromX = fieldAccess.getValue("FromX")
                fromY = fieldAccess.getValue("FromY")
                fromZ = fieldAccess.getValue("FromZ")
                toX = fieldAccess.getValue("ToX")
                toY = fieldAccess.getValue("ToY")
                toZ = fieldAccess.getValue("ToZ")
                sagDistance = fieldAccess.getValue("SagDistance")
                weightPerUnitLength = fieldAccess.getValue("WeightPerUnitLength")
                fromPointXYZ = vg.Point(fromX, fromY, fromZ)
                toPointXYZ = vg.Point(toX, toY, toZ)
                # Change to attachment point objects.
                fromPoint = create_3D_catenary.AttachmentPoint(fromPointXYZ, lineNumber, fromTower)
                toPoint = create_3D_catenary.AttachmentPoint(toPointXYZ, lineNumber, toTower)

                p("Initial sagDistance on feature:", sagDistance)

                # sag distance is None because we need to calculate it from the lineGuide
                # horizontal tension is not supplied.
                adjustedSpan = create_3D_catenary.makeSpan(fromPoint, toPoint, lc_guide_lines, weightPerUnitLength, None, None, None)
                newSpanDistance = adjustedSpan.sagDistance
                p("new sagDistance on feature:", newSpanDistance)

        if cursor:
            del cursor

        if lc_adjust_all:
            # We have already created the span with a sag distance.
            # For simplicity, we'll throw out that span object and make all six using that sag.
            adjustedSpans = []
            fieldList = ["FromTower", "ToTower", "LineNumber", "FromX", "FromY", "FromZ", "ToX", "ToY", "ToZ"]
            fieldAccess = utils.FieldAccess(fieldList)
            whereClause = "FromTower = " + str(fromTower) + " and ToTower = " + str(toTower)

            p("sagDistance for all lines", newSpanDistance)

            # search in full feature class, not just selection
            i = 0
            cursor = arcpy.da.SearchCursor(common_lib.get_full_path_from_layer(lc_guide_lines), fieldList, whereClause)
            for row in cursor:
                fieldAccess.setRow(row)
                lineNumber = fieldAccess.getValue("LineNumber")
                fromTower = fieldAccess.getValue("FromTower")
                toTower = fieldAccess.getValue("ToTower")
                fromX = fieldAccess.getValue("FromX")
                fromY = fieldAccess.getValue("FromY")
                fromZ = fieldAccess.getValue("FromZ")
                toX = fieldAccess.getValue("ToX")
                toY = fieldAccess.getValue("ToY")
                toZ = fieldAccess.getValue("ToZ")
                fromPointXYZ = vg.Point(fromX, fromY, fromZ)
                toPointXYZ = vg.Point(toX, toY, toZ)
                # Change to attachment point objects.
                fromPoint = create_3D_catenary.AttachmentPoint(fromPointXYZ, lineNumber, fromTower)
                toPoint = create_3D_catenary.AttachmentPoint(toPointXYZ, lineNumber, toTower)

                p("newSpanDistance in loop", newSpanDistance)
                adjustedSpan = create_3D_catenary.makeSpan(fromPoint, toPoint, common_lib.get_full_path_from_layer(lc_guide_lines), weightPerUnitLength, newSpanDistance, None)
                adjustedSpans.append(adjustedSpan)

                i+=1
                # arcpy.AddMessage(str(i))

            doSpanRemoveAndInsert(lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines), adjustedSpans)
        else:
            doSpanRemoveAndInsert(lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines), [adjustedSpan])

        if lc_use_in_memory:
            arcpy.Delete_management("in_memory")

        if lc_debug == 0:
            fcs = common_lib.listFcsInGDB(lc_scratch_ws)

            msg_prefix = "Deleting intermediate data..."

            msg_body = common_lib.create_msg_body(msg_prefix, 0, 0)
            common_lib.msg(msg_body)

            for fc in fcs:
                arcpy.Delete_management(fc)

        arcpy.ClearWorkspaceCache_management()

        return lc_catenary, common_lib.get_full_path_from_layer(lc_guide_lines)

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #6
0
def makeSways(span, max_angle):

    total_range = 2*max_angle
    angles = []

    if max_angle <= 45:
        nr_steps = 6
        step_size = int(total_range / nr_steps)
    else:
        step_size = 15

    if step_size > max_angle:
        step_size = max_angle

    for i in range(-max_angle, max_angle, step_size):
        angles.append(i)

    angles.append(max_angle)

    # Span was constructed in new 2D XZ plane, and we'll keep that convention here.
    # Some of this is redundant from makeSpan, but best option is make generic function in VG library
    # to rotate points/geometry around arbitrary 3D axis.
    spanVector3D = vg.getVectorFromTwoPoints(span.fromPoint, span.toPoint)
    spanVector2DNoZ = vg.Vector(spanVector3D.x, spanVector3D.y,0)
    spanLength2D = vg.magnitude(spanVector2DNoZ)
    spanVector3DNormalToSpanPlane = vg.crossProduct(spanVector3D, vg.Vector(0,0,1))
    spanVector3DNormalInSpanPlane = vg.crossProduct(spanVector3D, spanVector3DNormalToSpanPlane)
    attachmentPointHeightDifference = span.toPoint.z - span.fromPoint.z

    # Still using XZ for span plane.
    spanVector2DNoY = vg.Vector(spanLength2D, 0, attachmentPointHeightDifference)

    # Build point vectors.
    pointVectors = []
    spanPolyline = span.polyline
    points = spanPolyline.nodes
    firstPoint = points[0]
    for pointIndex in range(0, len(points)):
        thisPoint = points[pointIndex]
        vectPoint3D = vg.getVectorFromTwoPoints(firstPoint,thisPoint)
        vectPoint2DNoZ = vg.Vector(vectPoint3D.x, vectPoint3D.y,0)
        vectZ = vg.Vector(0,0,vectPoint3D.z)
        vectPoint2DMag = vg.magnitude(vectPoint2DNoZ)
        xMag = vectPoint2DMag
        vectX = vg.Vector(xMag,0,0)
        thisVect = vg.addVectors(vectX, vectZ)
        pointVectors.append(thisVect)
    pointVectorsInSpanPlane = pointVectors

    ################
    swayLines = []
    for angle in angles:
        # These vectors are in 2D XZ plane.
        swayPoints = []
        lastPointIndex = len(pointVectorsInSpanPlane) - 1
        for pointIndex in range(0, lastPointIndex + 1):
            pointVector = pointVectorsInSpanPlane[pointIndex]
            if pointIndex == 0:
                thisPoint = span.fromPoint
            elif pointIndex == lastPointIndex:
                thisPoint = span.toPoint
            else:
                pointVectorLength = vg.magnitude(pointVector)
                h = pointVectorLength
                t = vg.scalarProjection(pointVector, spanVector2DNoY)
                r = math.sqrt(pow(h,2) - pow(t,2))
                alpha = 90 - angle
                alphaRadians = math.radians(alpha)
                u = r * math.cos(alphaRadians)
                v = r * math.sin(alphaRadians)

                tVector = vg.setVectorMagnitude(spanVector3D, t)
                uVector = vg.setVectorMagnitude(spanVector3DNormalToSpanPlane, u)
                vVector = vg.setVectorMagnitude(spanVector3DNormalInSpanPlane, v)
                uvVector = vg.addVectors(uVector,vVector)
                tuvVector = vg.addVectors(tVector, uvVector)
                thisPoint = vg.copyNode(span.fromPoint, tuvVector)
            swayPoints.append(thisPoint)
        # END FOR pointIndex.
        thisSwayLine = vg.Polyline(swayPoints)
        swayLines.append(thisSwayLine)
    # END FOR angles
    span.swayLines = swayLines
    ################
    pass
コード例 #7
0
def makeSwayLinesAndSurfaces(lc_scratch_ws, lc_catenary, lc_angle, lc_output_features, lc_debug, lc_use_in_memory):
    try:
        includedSwayLinesFC = None
        includedSwaySurfacesFC = None
        sr = arcpy.Describe(lc_catenary).spatialReference

        geometry_type = "POLYLINE"
        has_m = "DISABLED"
        has_z = "ENABLED"
        from_tower_field = "FromTower"
        to_tower_field = "ToTower"
        tower_field = "Tower"
        line_number_field = "LineNumber"
        count_field = "COUNT"

        swaylines = "SwayLines"
        swaysurfaces = "SwaySurfaces"
        in_memory = "in_memory"

        spatial_reference = arcpy.Describe(lc_catenary).spatialReference

        includedSwayLinesFC = lc_output_features + "_swaylines"

        includedSwayLinesFC_dirname = os.path.dirname(includedSwayLinesFC)
        includedSwayLinesFC_basename = os.path.basename(includedSwayLinesFC)

        if arcpy.Exists(includedSwayLinesFC):
            arcpy.Delete_management(includedSwayLinesFC)

        arcpy.CreateFeatureclass_management(includedSwayLinesFC_dirname, includedSwayLinesFC_basename, geometry_type, "", has_m, has_z,
                                                    spatial_reference)

        common_lib.delete_add_field(includedSwayLinesFC, from_tower_field, "LONG")
        common_lib.delete_add_field(includedSwayLinesFC, to_tower_field, "LONG")
        common_lib.delete_add_field(includedSwayLinesFC, line_number_field, "LONG")
        common_lib.delete_add_field(includedSwayLinesFC, count_field, "LONG")

        geometry_type = "POLYGON"

        includedSwaySurfacesFC= os.path.join(lc_scratch_ws, "temp_sway_surfaces")

        includedSwaySurfacesFC_dirname = os.path.dirname(includedSwaySurfacesFC)
        includedSwaySurfacesFC_basename = os.path.basename(includedSwaySurfacesFC)

        if arcpy.Exists(includedSwaySurfacesFC):
            arcpy.Delete_management(includedSwaySurfacesFC)

        arcpy.CreateFeatureclass_management(includedSwaySurfacesFC_dirname, includedSwaySurfacesFC_basename, geometry_type, "", has_m, has_z,
                                                spatial_reference)

        common_lib.delete_add_field(includedSwaySurfacesFC, from_tower_field, "LONG")
        common_lib.delete_add_field(includedSwaySurfacesFC, to_tower_field, "LONG")
        common_lib.delete_add_field(includedSwaySurfacesFC, line_number_field, "LONG")
        common_lib.delete_add_field(includedSwaySurfacesFC, count_field, "LONG")

        arcpy.AddMessage("Creating sway surfaces...")

        # cycle through catenaries
        with arcpy.da.SearchCursor(lc_catenary, ['SHAPE@', 'FromTower', 'ToTower', 'LineNumber']) as cursor:
            for row in cursor:
                polyline = row[0]
                fromPoint = None
                toPoint = None

                # get start and end points from line, we assume 1 part
                for part in polyline:
                    for pnt in part:
                        if pnt:
                            ptGeom = arcpy.PointGeometry(pnt, sr)
                            line_length = polyline.length
                            chainage = polyline.measureOnLine(ptGeom)

                            if chainage == 0:  # start point
                                point = vg.Point(pnt.X, pnt.Y, pnt.Z)
                                fromPoint = create_3D_catenary.AttachmentPoint(point, row[3], row[1])

                            elif chainage - line_length == 0:  # end point
                                point = vg.Point(pnt.X, pnt.Y, pnt.Z)
                                toPoint = create_3D_catenary.AttachmentPoint(point, row[3], row[2])
                            else:  # in between points
                                continue
                # fill span object
                if fromPoint and toPoint:
                    span = create_3D_catenary.Span(fromPoint, toPoint)
                    catenary_line = vg.arcpyPolylineToVGPolyline(polyline)
                    span.polyline = catenary_line

                    makeSways(span, lc_angle)
                    makeSurfacePanels(span)

                    doInsert_SwayLinesSurfaces(includedSwayLinesFC, includedSwaySurfacesFC, [span])

                else:
                    arcpy.AddError("Error finding start and end points for catenary")

        if lc_use_in_memory:
            arcpy.Delete_management("in_memory")

        arcpy.ClearWorkspaceCache_management()

        return includedSwayLinesFC, includedSwaySurfacesFC

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #8
0
    def __init__(self, polyline, towerConfiguration, sagToSpanRatio, horizontalTension, lineWeight, endPoints):
        # Gert, I think TowerConfiguration was made to hold all of the GP inputs and those go into
        # the TowerBasePoints feature layer, along with a few others, to drive the RPK.
        # I considered adding sagToSpanRatio, horizontalTension, lineWeight to that layer,
        # for reference when inspecting the tower base points, but that would require new fields
        # (and I don't know your code that well),
        # so I just sent them into this function as args, instead of adding them into
        # TowerConfiguration object, which is a good place to store them, with all of the other GP inputs.
        self.polyline = polyline
        self.nodes = self.polyline.nodes
        self.towerBasePoints = []

        towerCount = len(polyline.nodes)
        for nodeIndex in range(0, towerCount):
            node = self.nodes[nodeIndex]
            towerBasePoint = TowerBasePoint(node)
            # For 1-based tower indexing.
            towerIndex = nodeIndex + 1
            towerBasePoint.towerNumber = towerIndex


            self.towerBasePoints.append(towerBasePoint)

        # Find tower directions, and max sag allowed per tower based on adjacent spans.
        # Note: there is one less span than there are towers.
        cardinalDirection = None
        greaterOfAdjacentSpanMaximumSags = None

        endPointGertArgument = endPoints

        for nodeIndex in range(0, towerCount):
            towerBasePoint = self.towerBasePoints[nodeIndex]
            towerBasePoint.structure_type = towerConfiguration.structure_type
            towerBasePoint.endPointGertArgument = endPointGertArgument
            # Note: Using 3D length here with sagRatio, so that steep lines get similar sag to flat lines.

            if nodeIndex == 0:
                # The first node's direction is pointing to the second node.
                thisTowerBasePoint = self.towerBasePoints[0]
                nextTowerBasePoint = self.towerBasePoints[1]
                fromPoint = thisTowerBasePoint.point
                toPoint = nextTowerBasePoint.point

                spanDirectionVector = vg.getVectorFromTwoPoints(fromPoint, toPoint)
                cardinalDirection = vg.getCardinalDirectionFromVector2D(spanDirectionVector)
                #spanVector3D = vg.getVectorFromTwoPoints(fromPoint, toPoint)
                #spanLength3D = vg.magnitude(spanVector3D)

                # Find max sag.
                # to get max_sag, we need AttachmentPoint objects for the makeSpan() function.
                thisFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(thisTowerBasePoint.point,0,0)
                nextFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(nextTowerBasePoint.point,0,0)

                nextSpan = create_3D_catenary.makeSpan(thisFakeAttachmentPoint, nextFakeAttachmentPoint, None, lineWeight, sagToSpanRatio, None, horizontalTension)
                greaterOfAdjacentSpanMaximumSags = nextSpan.sagDistance

                # Find endpoint type.
                if endPointGertArgument == "Both" or endPointGertArgument == "Start":
                    towerBasePoint.structure_type = "Substation"

            elif nodeIndex == towerCount - 1:
                # The last node takes its direction from previous node.
                thisTowerBasePoint = self.towerBasePoints[nodeIndex]
                previousTowerBasePoint = self.towerBasePoints[nodeIndex - 1]
                spanDirectionVector = vg.getVectorFromTwoPoints(previousTowerBasePoint.point, thisTowerBasePoint.point)
                cardinalDirection = vg.getCardinalDirectionFromVector2D(spanDirectionVector)

                # find max sag.
                thisFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(thisTowerBasePoint.point,0,0)
                previousFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(previousTowerBasePoint.point,0,0)

                previousSpan = create_3D_catenary.makeSpan(previousFakeAttachmentPoint, thisFakeAttachmentPoint, None, lineWeight, sagToSpanRatio, None, horizontalTension)
                greaterOfAdjacentSpanMaximumSags = previousSpan.sagDistance


                # Find endpoint type.
                if endPointGertArgument == "Both" or endPointGertArgument == "End":
                    towerBasePoint.structure_type = "Substation"

            else:
                # This node is in between first and last, and must handle direction changes.
                previousTowerBasePoint = self.towerBasePoints[nodeIndex - 1]
                thisTowerBasePoint = self.towerBasePoints[nodeIndex]
                nextTowerBasePoint = self.towerBasePoints[nodeIndex + 1]

                spanDirectionPrevious = vg.getVectorFromTwoPoints(previousTowerBasePoint.point, thisTowerBasePoint.point)
                spanDirectionThis = vg.getVectorFromTwoPoints(thisTowerBasePoint.point, nextTowerBasePoint.point)
                spanDirectionBisector = vg.getBisectingVector2D(spanDirectionPrevious, spanDirectionThis)
                cardinalDirection = vg.getCardinalDirectionFromVector2D(spanDirectionBisector)

                # find max sag.
                previousFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(previousTowerBasePoint.point,0,0)
                thisFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(thisTowerBasePoint.point,0,0)
                nextFakeAttachmentPoint = create_3D_catenary.AttachmentPoint(nextTowerBasePoint.point,0,0)

                previousSpan = create_3D_catenary.makeSpan(previousFakeAttachmentPoint, thisFakeAttachmentPoint, None, lineWeight, sagToSpanRatio, None, horizontalTension)
                nextSpan = create_3D_catenary.makeSpan(thisFakeAttachmentPoint, nextFakeAttachmentPoint, None, lineWeight, sagToSpanRatio, None, horizontalTension)

                greaterOfAdjacentSpanMaximumSags = greaterOf(previousSpan.sagDistance, nextSpan.sagDistance)

                # XX how could it have worked without the line below?
                towerBasePoint.structure_type = towerConfiguration.structure_type

            # Fields set for each tower.
            towerBasePoint.cardinalDirection = cardinalDirection
            towerBasePoint.maximum_sag_allowance = greaterOfAdjacentSpanMaximumSags
コード例 #9
0
def makeTowersAndJunctions(lc_scratch_ws, lc_rule_dir, lc_input_features, lc_testLineWeight, lc_sag_to_span_ratio, lc_horizontal_tension,
                                    lc_tower_configuration, lc_ends, lc_output_features,
                                    lc_debug, lc_use_in_memory):

    try:
        # Making Tower configuration object to hold fields for TowerBasePoints layer.
        towerConfiguration = lc_tower_configuration

        geometry_type = "POINT"
        has_m = "DISABLED"
        has_z = "ENABLED"

        in_memory = "in_memory"
        tower_placement_points_name = "TowerLocations"
        out_tower_models_name = "TowerModels"
        junction_intoFFCER = "JunctionPoints"
        junction_points_name = "JunctionPoints"
        CE_additionP = "_Points"
        CE_additionMP = "_MPoints"
        CE_additionL = "_Lines"
        spans_name = "Spans"

        exportPointsRPK = lc_rule_dir + "\\" + "TransmissionTower_ExportPoints.rpk"
        exportModelsRPK = lc_rule_dir + "\\" + "TransmissionTower_ExportModel.rpk"

        spatial_reference = arcpy.Describe(lc_input_features).spatialReference

        # create empty feature class with required fields
        msg_body = create_msg_body("Preparing output feature classes...", 0, 0)
        msg(msg_body)

        # create / check out features classes
        # tower placement points
        outTowerPlacementPoints = lc_output_features + "_" + tower_placement_points_name

        if arcpy.Exists(outTowerPlacementPoints):
            arcpy.Delete_management(outTowerPlacementPoints)

        # tower models: multipatches generated from tower placement points
        outTowerModels = lc_output_features + "_" + out_tower_models_name

        if arcpy.Exists(outTowerModels):
            arcpy.Delete_management(outTowerModels)

        outJunctionPointsFromFFCER = lc_output_features + "_" + junction_points_name

        if arcpy.Exists(outJunctionPointsFromFFCER):
            arcpy.Delete_management(outJunctionPointsFromFFCER)

        # output spans
        outSpansIntoScript = lc_output_features + "_" + spans_name

        if arcpy.Exists(outSpansIntoScript):
            arcpy.Delete_management(outSpansIntoScript)

        # NOTE: these items are used to create attributes and values must correspond to
        # TowerConfiguration attributes. If this list changes you must update TowerConfiguration object class

        # Tower RPK Fields, in TowerBasePoints layer.
        tower_number_field = "TowerNumber"
        units_field = "Units"
        cardinal_direction_field = "Cardinal_Direction"
        line_type_field = "Line_Type"
        structure_type_field = "Structure_Type"
        voltage_field = "Voltage"
        circuits_field = "Circuits"
        alignment_field = "Alignment"
        conductor_vertical_clearance_field = "Conductor_Vertical_Clearance"
        conductor_horizontal_clearance_field = "Conductor_Horizontal_Clearance"
        minimum_ground_clearance_field = "Minimum_Ground_Clearance"
        maximum_sag_allowance_field = "Maximum_Sag_Allowance"
        shield_wires_field = "Shield_Wires"
        insulator_hang_type_field = "Insulator_Hang_Type"
        beam_color_field = "Beam_Color"
        tower_material = "DistPole_Material"

        tower_base_point_field_dict = {cardinal_direction_field:"DOUBLE",
                                            tower_number_field:"LONG",
                                            line_type_field:"TEXT",
                                            structure_type_field:"TEXT",
                                            voltage_field:"TEXT",
                                            circuits_field:"LONG",
                                            alignment_field:"TEXT",
                                            conductor_vertical_clearance_field:"FLOAT",
                                            conductor_horizontal_clearance_field:"FLOAT",
                                            minimum_ground_clearance_field:"FLOAT",
                                            maximum_sag_allowance_field:"FLOAT",
                                            shield_wires_field:"LONG",
                                            insulator_hang_type_field:"TEXT",
                                            beam_color_field:"TEXT",
                                            units_field:"TEXT",
                                            tower_material: "TEXT"
                                       }

        catenary = None
        fieldList = ["SHAPE@"]
        fieldAccess = utils.FieldAccess(fieldList)

        num_features = int(arcpy.GetCount_management(lc_input_features).getOutput(0))

        lineCursor = arcpy.da.SearchCursor(lc_input_features, fieldList)
        i = 1

        for row in lineCursor:
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                # junctions points needed for FFCER
                outJunctionPointsIntoFFCER = in_memory + "/" + junction_intoFFCER

            else:
                # junctions points needed for makeSpans: FFCER generates 3D points with _Points in name
                outJunctionPointsIntoFFCER = os.path.join(lc_scratch_ws, junction_intoFFCER)

            if arcpy.Exists(outJunctionPointsIntoFFCER):
                arcpy.Delete_management(outJunctionPointsIntoFFCER)

            # delete additional CE output
            if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionP):
                arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionP)

            if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionMP):
                arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionMP)

            if arcpy.Exists(outJunctionPointsIntoFFCER + CE_additionL):
                arcpy.Delete_management(outJunctionPointsIntoFFCER + CE_additionL)

                # create temporary per line feature classes
                # temp tower placement points
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outTowerPlacementPoints = in_memory + "/" + tower_placement_points_name + "_temp"

            else:
                temp_outTowerPlacementPoints = os.path.join(lc_scratch_ws, tower_placement_points_name + "_temp")

            # first time delete just to be sure
            if i == 1 and arcpy.Exists(temp_outTowerPlacementPoints):
                arcpy.Delete_management(temp_outTowerPlacementPoints)

            if arcpy.Exists(temp_outTowerPlacementPoints):
                arcpy.TruncateTable_management(temp_outTowerPlacementPoints)
            else:
                temp_outtowerPlacementPoints_dirname = os.path.dirname(temp_outTowerPlacementPoints)
                temp_outtowerPlacementPoints_basename = os.path.basename(temp_outTowerPlacementPoints)

                arcpy.CreateFeatureclass_management(temp_outtowerPlacementPoints_dirname,
                                                    temp_outtowerPlacementPoints_basename,
                                                    geometry_type, "", has_m, has_z,
                                                    spatial_reference)
                # add required fields for towerPlacementPoints
                arcpy.AddMessage("Adding required fields to tower placement points...")

                start_time = time.clock()

#                for k, v in tower_base_point_field_dict.items():
#                    common_lib.delete_add_field(temp_outTowerPlacementPoints, k, v)

                listoffields = []
                for k, v in tower_base_point_field_dict.items():
                    field = []
                    field.append(k)
                    field.append(v)
                    listoffields.append(field)

                arcpy.management.AddFields(temp_outTowerPlacementPoints, listoffields)

                end_time = time.clock()
                msg_body = create_msg_body("Time to create fields...", start_time,
                                           end_time)
                msg(msg_body)

            # temp tower models: multipatches generated from tower placement points
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outTowerModels = in_memory + "/" + out_tower_models_name + "_temp"
            else:
                temp_outTowerModels = os.path.join(lc_scratch_ws, out_tower_models_name + "_temp")

            if arcpy.Exists(temp_outTowerModels):
                arcpy.Delete_management(temp_outTowerModels)

            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outJunctionPointsFromFFCER = in_memory + "/" + out_tower_models_name + "_temp"

            else:
                temp_outJunctionPointsFromFFCER = os.path.join(lc_scratch_ws, junction_points_name + "_temp")

            if arcpy.Exists(temp_outJunctionPointsFromFFCER):
                arcpy.Delete_management(temp_outJunctionPointsFromFFCER)

            # output temp spans
            if lc_use_in_memory:
                arcpy.AddMessage("Using in memory for processing")

                temp_outSpansIntoScript = in_memory + "/" + spans_name + "_temp"

            else:
                temp_outSpansIntoScript = os.path.join(lc_scratch_ws, spans_name + "_temp")

            if arcpy.Exists(temp_outSpansIntoScript):
                arcpy.Delete_management(temp_outSpansIntoScript)

            # multiple lines are now supported...
            if i >= 0:
                fieldAccess.setRow(row)

                arcpyPolyline = fieldAccess.getValue("SHAPE@")

                # read the line
                vgPolyline = vg.arcpyPolylineToVGPolyline(arcpyPolyline)
                if vgPolyline:
                    # get tower point objects here. Initializing TowerPlacementLine builds the TowerBasePoints.
                    # from towerConfiguration
                    pint("Preparing tower base points for feature: " + str(i) + " out of " + str(num_features) + ".")

                    towerPlacementLine = TowerPlacementLine(vgPolyline, towerConfiguration, lc_sag_to_span_ratio, lc_horizontal_tension, lc_testLineWeight, lc_ends)
                    towerBasePoints = towerPlacementLine.towerBasePoints
                    # put the tower base points into the scene.
                    InsertTowerBasePoints(towerBasePoints, towerConfiguration, temp_outTowerPlacementPoints, list(tower_base_point_field_dict.keys()))
                    arcpy.ddd.FeaturesFromCityEngineRules(temp_outTowerPlacementPoints, exportPointsRPK,
                                                          outJunctionPointsIntoFFCER, "DROP_EXISTING_FIELDS",
                                                          "INCLUDE_REPORTS", "FEATURE_PER_LEAF_SHAPE")

                    # TODO built in check when FFCER fails XX Gert

                    # copy _Points fc to input gdb
                    arcpy.CopyFeatures_management(outJunctionPointsIntoFFCER + CE_additionP, temp_outJunctionPointsFromFFCER)

                    arcpy.ddd.FeaturesFromCityEngineRules(temp_outTowerPlacementPoints, exportModelsRPK,
                                                          temp_outTowerModels, "INCLUDE_EXISTING_FIELDS",
                                                          "EXCLUDE_REPORTS", "FEATURE_PER_SHAPE")

                    pint("Making spans for feature: " + str(i) + " out of " + str(num_features) + ".")

                    catenary, guide_lines = create_3D_catenary.makeSpans(lc_scratch_ws=lc_scratch_ws,
                                                        lc_inPoints=temp_outJunctionPointsFromFFCER,
                                                        lc_testLineWeight=lc_testLineWeight,
                                                        lc_sag_to_span_ratio=lc_sag_to_span_ratio,
                                                        lc_horizontal_tension=lc_horizontal_tension,
                                                        lc_output_features=temp_outSpansIntoScript,
                                                        lc_debug=lc_debug,
                                                        lc_use_in_memory=False,
                                                        lc_cleanup=False,
                                                        lc_caller=TOOLNAME)

                    # append features to output feature classes

                    # catenary, outTowerModels, outJunctionPointsFromFFCER, outTowerPlacementPoints
                    schemaType = "NO_TEST"
                    if arcpy.Exists(outSpansIntoScript):
                        arcpy.Append_management(catenary, outSpansIntoScript, schemaType)
                    else:
                        arcpy.Copy_management(catenary, outSpansIntoScript)

                    pint("Made spans for feature: " + str(i) + " out of " + str(num_features) + ".")

                    if arcpy.Exists(outTowerModels):
                        arcpy.Append_management(temp_outTowerModels, outTowerModels, schemaType)
                    else:
                        arcpy.Copy_management(temp_outTowerModels, outTowerModels)

                    pint("Made towers for feature: " + str(i) + " out of " + str(num_features) + ".")

                    if arcpy.Exists(outJunctionPointsFromFFCER):
                        arcpy.Append_management(temp_outJunctionPointsFromFFCER, outJunctionPointsFromFFCER, schemaType)
                    else:
                        arcpy.Copy_management(temp_outJunctionPointsFromFFCER, outJunctionPointsFromFFCER)

                    pint("Made junctions for feature: " + str(i) + " out of " + str(num_features) + ".")

                    if arcpy.Exists(outTowerPlacementPoints):
                        arcpy.Append_management(temp_outTowerPlacementPoints, outTowerPlacementPoints, schemaType)
                    else:
                        arcpy.Copy_management(temp_outTowerPlacementPoints, outTowerPlacementPoints)
                else:
                    raise MultipartInputNotSupported

            i += 1

        return outSpansIntoScript, outTowerModels, outJunctionPointsFromFFCER, outTowerPlacementPoints

    except MultipartInputNotSupported:
        print("Multipart features are not supported. Exiting...")
        arcpy.AddError("Multipart features are not supported. Exiting...")

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #10
0
def makeSpan(fromPoint, toPoint, lc_includedTransmissionLineGuides, lc_testLineWeight, sagToSpanRatio, sagDistance, horizontalTension):
    try:
        span = Span(fromPoint, toPoint)
        # Define span shape here, then set polyline on Span object.
        spanVector3D = vg.getVectorFromTwoPoints(fromPoint, toPoint)
        spanLength3D = vg.magnitude(spanVector3D)
        spanVector2DNoZ = vg.Vector(spanVector3D.x, spanVector3D.y, 0)
        spanLength2D = vg.magnitude(spanVector2DNoZ)
        fromTower = fromPoint.towerNumber
        toTower = toPoint.towerNumber
        lineNumber = fromPoint.lineNumber
        attachmentPointHeightDifference = abs(toPoint.z - fromPoint.z)
        lineWeightPerUnitLength = lc_testLineWeight

        # NOTE: The logic below depends on which script calls the function.
        # When called from create_3D_catenary(this script), inside makeSpans() function,
        # new spans are created based on horizontal tension, and sagDistance is calculated.

        # When called from adjust_3D:
        # It is called once with sagDistance of None which triggers use of line guide.
        # Once sagDistance is known, if "adjust all" tool option is used, then sagDistance is used to
        # make the matching spans, so sagDistance is not None.

        w = lineWeightPerUnitLength
        H = None
        # When called from create_3D_catenary_from_line, GP tool might send sagToSpanRatio:
        if sagToSpanRatio is not None:
            D = sagToSpanRatio * spanLength2D

        # When called from create_3D_catenary_from_line, GP tool might send horizontal tension:
        elif horizontalTension is not None:
            # Using sag approximation until I find better formula.
            # XX This method doesn't work with the degree of accuracy needed, but is close enough and will be visually corrected.
            H = horizontalTension
            catenaryConstant = H/w
            sOver2 = spanLength3D/2
            inverseCatenaryConstant = w/H
            coshValue = math.cosh(sOver2 * inverseCatenaryConstant)
            coshValueMinusOne = coshValue - 1
            sagApproximation = catenaryConstant * coshValueMinusOne
            D = sagApproximation

        # When called from adjust_3D_catenary the first time sagDistance is None:
        elif sagDistance is None and lc_includedTransmissionLineGuides is not None:

            # Query LineGuides for line with matching from, to, and line.
            fieldListLineGuides = ["SHAPE@", "FromTower", "ToTower", "LineNumber"]
            fieldAccessLineGuides = utils.FieldAccess(fieldListLineGuides)
            whereClauseLineGuides = "FromTower = " + str(fromTower) + " and ToTower = " + str(
                toTower) + " and LineNumber = " + str(lineNumber)
            cursor = arcpy.da.SearchCursor(lc_includedTransmissionLineGuides, fieldListLineGuides, whereClauseLineGuides)

            msg_body = create_msg_body("Creating span for line number " + str(lineNumber) + " from tower " + str(
                                                                    fromTower) + " to tower " + str(toTower) + ".", 0, 0)
            msg(msg_body)

            # default lineGuideZ for when none exists. This ensures no square root of zero causes error.
            #  XX In what part? The calculation of D, I guess.
            #  XX This brings up a question... Will this entire function work if both points are at same z? That would be very unlikely.
            lineGuideZ = None
            if fromPoint.z > toPoint.z:
                defaultLineGuideZ = toPoint.z - 10
            else:
                defaultLineGuideZ = fromPoint.z - 10

            for row in cursor:
                fieldAccessLineGuides.setRow(row)
                lineGuideShape = fieldAccessLineGuides.getValue("SHAPE@")
                lineGuide = vg.arcpyPolylineToVGPolyline(lineGuideShape)
                lineGuideZ = lineGuide.nodes[0].z
            if cursor:
                del cursor

            # If no user line exists, this span has not been run yet, so use default.
            # Only issue warning if user-adjusted line is above either attachment point.
            if lineGuideZ is None:
                lineGuideZ = defaultLineGuideZ
            elif lineGuideZ > fromPoint.z or lineGuideZ > toPoint.z:
                arcpy.AddWarning("Warning: Match line placed above lowest point.")
                lineGuideZ = defaultLineGuideZ

            # Redundant with Tension case above:
            if fromPoint.z > toPoint.z:
                dLow = toPoint.z - lineGuideZ
                hSign = 1
            else:
                dLow = fromPoint.z - lineGuideZ
                hSign = -1

            h = attachmentPointHeightDifference
            dHigh = dLow + h

            h_over4 = (h / 4) * hSign
            sqrtDLow = math.sqrt(dLow)
            sqrtDHigh = math.sqrt(dHigh)
            lowPlusHigh = sqrtDLow + sqrtDHigh
            lowMinusHigh = sqrtDLow - sqrtDHigh
            lowPlusHigh_over_lowMinusHigh = lowPlusHigh / lowMinusHigh
            D = h_over4 * lowPlusHigh_over_lowMinusHigh

        else:
            # When called from adjust_3D_catenary the second time, sagDistance is supplied:
            D = sagDistance


        #############################################################
        #############################################################
        # Sag is determined now.
        # The next part creates a function to calculate the catenary height (z-value) along a 2D line from tower to tower.

        # variables from the diagram:
        S = spanLength2D
        h = attachmentPointHeightDifference
        w = lineWeightPerUnitLength  # lb/ft

        xHigh = (S / 2) * (1 + (h / (4 * D)))
        xLow = (S / 2) * (1 - (h / (4 * D)))


        dHigh = D * pow((1 + (h / (4 * D))), 2) # D sub L in book.
        dLow = D * pow((1 - (h / (4 * D))), 2)  # D sub R in book. # XX This is reversed, because the book chose left and right, rather than high and low.

        if H is None: # else horizontal tension was supplied.
            hLow = (w * pow(xLow, 2)) / (2 * dLow)
            #hHigh = (w * pow(xHigh, 2)) / (2 * dHigh)
            H = hLow  # or hHigh, because they must be equal.


        # Use external function for 3D polyline (below).
        makeSpanPolylineShapeAndLineGuide(span, xHigh, xLow, dHigh, dLow, H, w)


        # LineLength (uses these values from above calculations):
        # S = spanLength2D
        # xLow, xHigh
        # w = lineWeightPerUnitLength
        # H = Horizontal tension
        xRcubed_plus_xLcubed = pow(abs(xLow), 3) + pow(xHigh, 3) #XX note the abs!
        wSquared_over_6HSquared = pow(w, 2) / (6 * pow(H, 2))
        L = S + (xRcubed_plus_xLcubed * wSquared_over_6HSquared)

        # Save span data for span feature class.
        span.sagDistance = D
        span.horizontalTension = H
        span.lineLength = L
        span.weightPerUnitLength = w

        return span

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #11
0
def makeSpans(lc_scratch_ws, lc_inPoints, lc_testLineWeight, lc_sag_to_span_ratio, lc_horizontal_tension, lc_output_features, lc_debug, lc_use_in_memory, lc_cleanup, lc_caller):
    try:
        geometry_type = "POLYLINE"
        has_m = "DISABLED"
        has_z = "ENABLED"
        from_tower_field = "FromTower"
        to_tower_field = "ToTower"
        line_number_field = "LineNumber"
        count_field = "COUNT"

        from_X_field = "FromX"
        from_Y_field = "FromY"
        from_Z_field = "FromZ"
        To_X_field = "ToX"
        To_Y_field = "ToY"
        To_Z_field = "ToZ"
        sag_distance = "SagDistance"
        horizontal_tension = "HorizontalTension"
        line_lenght = "LineLength"
        weight_per_unit_length = "WeightPerUnitLength"

        transmission_line_name = "TransmissionLines3D"
        transmission_guide_name = "TransmissionLineGuide"
        in_memory = "in_memory"

        spatial_reference = arcpy.Describe(lc_inPoints).spatialReference

        # create empty feature class with required fields

#        msg_body = create_msg_body("Preparing output feature classes...", 0, 0)
#        msg(msg_body)

        if lc_use_in_memory:
            arcpy.AddMessage("Using in memory for processing")
            includedTransmissionLinesFC = in_memory + "/" + transmission_line_name

            arcpy.CreateFeatureclass_management(in_memory, transmission_line_name, geometry_type, "", has_m, has_z, spatial_reference)
        else:
            includedTransmissionLinesFC = lc_output_features + "_3D"

            includedTransmissionLinesFC_dirname = os.path.dirname(includedTransmissionLinesFC)
            includedTransmissionLinesFC_basename = os.path.basename(includedTransmissionLinesFC)

            if arcpy.Exists(includedTransmissionLinesFC):
                arcpy.Delete_management(includedTransmissionLinesFC)

            arcpy.CreateFeatureclass_management(includedTransmissionLinesFC_dirname, includedTransmissionLinesFC_basename, geometry_type, "", has_m, has_z,
                                                    spatial_reference)

        fields1_dict = {from_tower_field:"LONG",
                            to_tower_field:"LONG",
                            line_number_field:"LONG",
                            count_field:"LONG",
                            sag_distance:"DOUBLE",
                            horizontal_tension:"DOUBLE",
                            line_lenght:"DOUBLE",
                            weight_per_unit_length:"DOUBLE"
                        }

        listoffields1 = []
        for k, v in fields1_dict.items():
            field = []
            field.append(k)
            field.append(v)
            listoffields1.append(field)

        arcpy.management.AddFields(includedTransmissionLinesFC, listoffields1)

#        common_lib.delete_add_field(includedTransmissionLinesFC, from_tower_field, "LONG")
#        common_lib.delete_add_field(includedTransmissionLinesFC, to_tower_field, "LONG")
#        common_lib.delete_add_field(includedTransmissionLinesFC, line_number_field, "LONG")
#        common_lib.delete_add_field(includedTransmissionLinesFC, count_field, "LONG")
#        common_lib.delete_add_field(includedTransmissionLinesFC, sag_distance, "DOUBLE")
#        common_lib.delete_add_field(includedTransmissionLinesFC, horizontal_tension, "DOUBLE")
#        common_lib.delete_add_field(includedTransmissionLinesFC, line_lenght, "DOUBLE")
#        common_lib.delete_add_field(includedTransmissionLinesFC, weight_per_unit_length, "DOUBLE")

        if lc_caller == "Create3Dcatenaryfromline":
            create_guidelines = False
        else:
            create_guidelines = True

        if create_guidelines:
            if lc_use_in_memory:
                includedTransmissionLineGuides = in_memory + "/" + transmission_guide_name

                arcpy.CreateFeatureclass_management(in_memory, transmission_guide_name, geometry_type, "", has_m, has_z, spatial_reference)
            else:
                includedTransmissionLineGuides = lc_output_features + "_LineGuides_3D"

                includedTransmissionLinesGuides_dirname = os.path.dirname(includedTransmissionLineGuides)
                includedTransmissionLinesGuides_basename = os.path.basename(includedTransmissionLineGuides)

                if arcpy.Exists(includedTransmissionLineGuides):
                    arcpy.Delete_management(includedTransmissionLineGuides)

                arcpy.CreateFeatureclass_management(includedTransmissionLinesGuides_dirname, includedTransmissionLinesGuides_basename, geometry_type, "", has_m, has_z,
                                                    spatial_reference)

            fields2_dict = {from_tower_field: "LONG",
                                to_tower_field: "LONG",
                                line_number_field: "LONG",
                                from_X_field: "DOUBLE",
                                from_Y_field: "DOUBLE",
                                from_Z_field: "DOUBLE",
                                To_X_field: "DOUBLE",
                                To_Y_field: "DOUBLE",
                                To_Z_field: "DOUBLE",
                                count_field: "LONG",
                                sag_distance: "DOUBLE",
                                weight_per_unit_length: "DOUBLE"
                            }

            listoffields2 = []
            for k, v in fields2_dict.items():
                field = []
                field.append(k)
                field.append(v)
                listoffields2.append(field)

            arcpy.management.AddFields(includedTransmissionLineGuides, listoffields2)

#            common_lib.delete_add_field(includedTransmissionLineGuides, from_tower_field, "LONG")
#            common_lib.delete_add_field(includedTransmissionLineGuides, to_tower_field, "LONG")
#            common_lib.delete_add_field(includedTransmissionLineGuides, line_number_field, "LONG")
#            common_lib.delete_add_field(includedTransmissionLineGuides, from_X_field, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, from_Y_field, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, from_Z_field, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, To_X_field, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, To_Y_field, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, To_Z_field, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, sag_distance, "DOUBLE")
#            common_lib.delete_add_field(includedTransmissionLineGuides, weight_per_unit_length, "DOUBLE")
        else:
            includedTransmissionLineGuides = None

        ############################################################################################### Chris continues...................
        attachmentPointList = []

        fieldList = ["SHAPE@X", "SHAPE@Y", "SHAPE@Z", "Line", "Tower"]
        fieldAccess = utils.FieldAccess(fieldList)
        cursor = arcpy.da.SearchCursor(lc_inPoints, fieldList)
        for row in cursor:
            fieldAccess.setRow(row)
            x = fieldAccess.getValue("SHAPE@X")
            y = fieldAccess.getValue("SHAPE@Y")
            z = fieldAccess.getValue("SHAPE@Z")
            lineNumber = fieldAccess.getValue("Line")
            towerNumber = fieldAccess.getValue("Tower")
            point = vg.Point(x, y, z)
            attachmentPoint = AttachmentPoint(point, lineNumber, towerNumber)
            attachmentPointList.append(attachmentPoint)
        if cursor:
            del cursor

        # Organize points into lists per line.
        dictionaryOfListsOfAttachmentPointsPerLine = {}
        for attachmentPoint in attachmentPointList:
            lineNumber = attachmentPoint.lineNumber
            if lineNumber in dictionaryOfListsOfAttachmentPointsPerLine.keys():
                listOfAttachmentPointsPerLine = dictionaryOfListsOfAttachmentPointsPerLine[lineNumber]
            else:
                listOfAttachmentPointsPerLine = []
                dictionaryOfListsOfAttachmentPointsPerLine[lineNumber] = listOfAttachmentPointsPerLine
            listOfAttachmentPointsPerLine.append(attachmentPoint)

        # Sort attachment points in each line list.
        # And make a list of line numbers for use in another dictionary.
        dictionaryOfSpanListsPerLine = {}
        lineNumberList = []
        for lineNumber in dictionaryOfListsOfAttachmentPointsPerLine.keys():
            lineNumberList.append(lineNumber)
            listOfAttachmentPointsPerLine = dictionaryOfListsOfAttachmentPointsPerLine[lineNumber]
            listOfAttachmentPointsPerLineSorted = sorted(listOfAttachmentPointsPerLine, key=lambda attachmentPoint: attachmentPoint.towerNumber)
            spanListPerThisLine = []
            for index in range(0, len(listOfAttachmentPointsPerLineSorted) - 1):
                fromPoint = listOfAttachmentPointsPerLineSorted[index]
                toPoint = listOfAttachmentPointsPerLineSorted[index + 1]

                # This is to give shield wires less sag, but only works when using the Easy Way.
                sagToSpanRatioForMakeSpan = None
                if lc_sag_to_span_ratio is not None:
                    sagToSpanRatioForMakeSpan = lc_sag_to_span_ratio
                    if lineNumber < 0:
                        sagToSpanRatioForMakeSpan = sagToSpanRatioForMakeSpan * 0.5

                span = makeSpan(fromPoint, toPoint, includedTransmissionLineGuides, lc_testLineWeight, sagToSpanRatio=sagToSpanRatioForMakeSpan,sagDistance=None, horizontalTension=lc_horizontal_tension)
                spanListPerThisLine.append(span)
            dictionaryOfSpanListsPerLine[lineNumber] = spanListPerThisLine

#        msg_body = create_msg_body("Writing all span lines to " + includedTransmissionLinesFC_basename + ".", 0, 0)
#        msg(msg_body)

        for index in range(0,len(lineNumberList)):
            lineNumber = lineNumberList[index]
            spanListPerThisLine = dictionaryOfSpanListsPerLine[lineNumber]
            # not TODO: CW, yes is has to run: switch is driven by includedTransmissionLineGuides inside the function.
            doInsertSpanAndGuideLine(includedTransmissionLinesFC, includedTransmissionLineGuides, spanListPerThisLine)

        if includedTransmissionLineGuides is not None:  # not TODO: CW, nope: see inside doInsertSpanAndGuideLine but could be coded more elegantly
            msg_body = create_msg_body(
                "Created helper Guide Lines feature class " + common_lib.get_name_from_feature_class(includedTransmissionLineGuides) + ".", 0, 0)
            msg(msg_body)

        # TODO check when necessary. When called from create_3D_catenary_from_line, this should not be called.

        if lc_cleanup:
            if lc_use_in_memory:
                arcpy.Delete_management("in_memory")

            if lc_debug == 0:
                fcs = common_lib.listFcsInGDB(lc_scratch_ws)

                msg_prefix = "Deleting intermediate data..."

                msg_body = common_lib.create_msg_body(msg_prefix, 0, 0)
                common_lib.msg(msg_body)

                for fc in fcs:
                    arcpy.Delete_management(fc)

            arcpy.ClearWorkspaceCache_management()

        return includedTransmissionLinesFC, includedTransmissionLineGuides

    except arcpy.ExecuteError:
        # Get the tool error messages
        msgs = arcpy.GetMessages(2)
        arcpy.AddError(msgs)
    except Exception:
        e = sys.exc_info()[1]
        arcpy.AddMessage("Unhandled exception: " + str(e.args[0]))
    pass
コード例 #12
0
def makeSpanPolylineShapeAndLineGuide(span, xHigh, xLow, dHigh, dLow, H, w):
    fromPoint = span.fromPoint
    toPoint = span.toPoint
    spanVector3D = vg.getVectorFromTwoPoints(fromPoint, toPoint)
    spanVector2DNoZ = vg.Vector(spanVector3D.x, spanVector3D.y, 0)
    spanLength2D = vg.magnitude(spanVector2DNoZ)
    # Make a list of values along the length of the span.
    # listZ holds the calculated z-values of each point on the line (relative to a flat 2D line between the towers).
    listZ = []
    # listT
    listT = []
    #Function z(t) is parameterized from 0 to 1 in X direction.
    def zAsAFunctionOfX(_x, _h, _w):
        a = _h / _w
        coshXoverA = math.cosh(_x / a)
        coshXoverA_MinusOne = coshXoverA - 1
        a_times_coshXoverA_MinusOne = a * coshXoverA_MinusOne
        z = a_times_coshXoverA_MinusOne
        return z

    for xStep in range(0, 101, 1):
        # T is moving from fromTower to toTower.
        T = (xStep * spanLength2D) / 100
        listT.append(T)
        # X origin is at lowest point in span, and x is positive in both directions.
        if fromPoint.z > toPoint.z:
            sagOriginDrop = dHigh
            # XX This condition is to handle a condition when an X value is negative... not sure about it. (uplift)
            if xHigh < 0:
                xAsFunctionOfT = abs(xHigh) + T
            else:
                xAsFunctionOfT = abs(T - xHigh)
        else:
            sagOriginDrop = dLow
            # XX This condition is to handle a condition when an X value is negative... not sure about it. (uplift)
            if xLow < 0:
                xAsFunctionOfT = abs(xLow) + T
            else:
                xAsFunctionOfT = abs(T - xLow)

        x = xAsFunctionOfT
        zValue = zAsAFunctionOfX(x, H, w)
        listZ.append(zValue)

    # XX Visual correction code is here!!!  This is just a fix, until we have someone with math or industry knowledge.

    firstZCalced = listZ[0] # z-relative to sag origin
    lastZCalced = listZ[-1] # z-relative to sag origin
    fromPointZ = span.fromPoint.z # feature z-value
    toPointZ = span.toPoint.z # feature z-value
    firstZCalcedPlusSagOriginDrop = firstZCalced + sagOriginDrop #CW TODO ref before init (maybe this was fixed?) maybe I got a runtime error for this? Too many weeks back.
    firstFixZ  = sagOriginDrop - firstZCalced
    firstElevDiff = fromPointZ - firstZCalcedPlusSagOriginDrop
    lastZCalcedPlusSagOriginDrop = lastZCalced + sagOriginDrop
    lastElevDiff = toPointZ - lastZCalcedPlusSagOriginDrop
    totalShearZ = lastElevDiff - firstElevDiff
    shearZIncrement = (totalShearZ / 100)


    # The is where we are calculating the line shape based on the known z-values determined above.
    # Start at fromPoint, and drop it by sag.
    sagDropVector = vg.Vector(0, 0, -sagOriginDrop)
    sagOriginPoint = vg.copyNode(fromPoint, sagDropVector)
    pointsForSpanPolyline = []
    for index in range(0, len(listT)):
        xAlongSpanVector = vg.setVectorMagnitude(spanVector2DNoZ, listT[index])
        shearZ = shearZIncrement * index # shearZ is part of visual fix
        zMoveUpValue = listZ[index] + firstFixZ + shearZ # firstFixZ is part of visual fix.
        zMoveUpVector = vg.Vector(0, 0, zMoveUpValue)
        originPointMoveVector = vg.addVectors(xAlongSpanVector, zMoveUpVector)
        thisPoint = vg.copyNode(sagOriginPoint, originPointMoveVector)
        pointsForSpanPolyline.append(thisPoint)


    # Make line shape from points.
    span.polyline = vg.Polyline(pointsForSpanPolyline)

    # Make lineGuide.
    lineGuideEndPoint = vg.copyNode(sagOriginPoint, spanVector2DNoZ)
    lineGuide = vg.Polyline([sagOriginPoint, lineGuideEndPoint])
    span.lineGuide = lineGuide

    pass