Example #1
0
    def process(self, input_fc, output_fc, use_template='false'):

        template = None
        if use_template == 'true':
            template = input_fc

        #get the directory, filename, and spatial reference
        sp_ref = Describe(input_fc).spatialReference
        directory, filename = Split_Path(output_fc)

        #create a new feature class
        AddMessage('Creating feature class {}'.format(output_fc))
        CreateFeatureclass_management(directory, filename, 'POINT', template,
                                      'DISABLED', 'DISABLED', sp_ref)

        #copy the geometry centroid
        AddMessage('Extracting endpoints...')
        line_to_endpoints(input_fc, output_fc)
    def execute(self, params, messages):
        """
        The source code of the tool
        """
        input_fc = params[_input_fc].valueAsText
        output_fc = params[_output_fc].valueAsText
        use_template = params[_use_template].valueAsText

        template = None
        if use_template == 'true':
            template = input_fc

        #get the directory, filename, and spatial reference
        sp_ref = Describe(input_fc).spatialReference
        directory, filename = Split_Path(output_fc)

        #create a new feature class
        messages.addMessage('Creating feature class {}'.format(output_fc))
        CreateFeatureclass_management(directory, filename, 'POINT', template,
                                      'DISABLED', 'DISABLED', sp_ref)

        #copy the geometry centroid
        messages.addMessage('Copying polygon centroids...')
        polygon_to_point(input_fc, output_fc)
def createShortGradiculeLinesForEachCounty():
    # Get/use the same projection as the one used for the county roads.
    spatialReferenceProjection = Describe(
        sharedNonStateSystem).spatialReference

    env.workspace = sqlGdbLocation

    inputCountyGradicule = countyCountyGradicule
    bufferedCounties = 'bufferedCounties'
    countiesToCopy = 'countiesToCopy'
    gradiculeToCopy = 'gradiculeToCopy'
    loadedGradiculeCopy = 'loadedGradiculeCopy'
    loadedTempGradicule = 'loadedTempGradicule'
    #unBufferedCounties = 'unBufferedCounties'
    # Using the miniBuffered process changes it from
    # 1457 total output features to 1481 (at 2.1k)
    # total output features.
    miniBufferedCounties = 'miniBufferedCounties'
    loadedOutputGradicule = 'loadedOutputGradicule'
    tempCounties = r'in_memory\tempCounties'
    tempCountyGradicule = r'in_memory\tempCountyGradicule'
    tempCountyGradiculePostErase = r'in_memory\tempCountyGradiculePostErase'
    tempCountyGradiculeSinglePart = r'in_memory\tempCountyGradiculeSinglePart'
    bufferCursorFields = ["OBJECTID", "COUNTY_NAME"]

    MakeFeatureLayer_management(sharedCounties, countiesToCopy)

    MakeFeatureLayer_management(countyCountyGradicule, gradiculeToCopy)
    CopyFeatures_management(gradiculeToCopy, countyGradiculeCopied)
    MakeFeatureLayer_management(countyGradiculeCopied, loadedGradiculeCopy)

    # Might be worth dissolving based on COORD & County_Name prior
    # to removing the County_Name field, if that's a possibility.

    # Or better yet, just make it so that the Gradicule lines for
    # a particular county are eligible for intersecting and
    # erasing with that same county's polygon's.  All we're
    # trying to do here is make it so that the county's original
    # gradicule lines are about half of their original size.
    # Don't need to find out which gradicule lines are close to
    # the county or anything else like that. Just need to reduce
    # the size of the lines and keep the parts that are nearest
    # the county that they go with.

    # Remove the County_Name field so that the intersect can add it
    # back and populate it only where the county buffer actually
    # intersects the lines.
    #DeleteField_management(countyGradiculeCopied, "County_Name")

    # Elaine requested that this be 1000 Feet shorter.
    # I made it 2000 feet shorter, because it still seemed too big.
    Buffer_analysis(sharedCounties, countiesBuffered, "8000 Feet")
    Buffer_analysis(sharedCounties, countiesMiniBuffered, "1500 Feet")

    bufferedCountyPolygonList = list()
    outputFeatureList = list()

    # 1st SearchCursor
    newCursor = daSearchCursor(countiesBuffered, bufferCursorFields)
    for newRow in newCursor:
        bufferedCountyPolygonList.append(list(newRow))

    if 'newCursor' in locals():
        del newCursor
    else:
        pass

    MakeFeatureLayer_management(countiesBuffered, bufferedCounties)
    MakeFeatureLayer_management(countiesMiniBuffered, miniBufferedCounties)

    loadedCountiesFields = ListFields(bufferedCounties)

    for loadedCountiesField in loadedCountiesFields:
        print "A loadedCountiesField was found: " + str(
            loadedCountiesField.name)

    countyGradiculeFields = ListFields(loadedGradiculeCopy)

    for countyGradiculeField in countyGradiculeFields:
        print "A countyGradiculeField was found: " + str(
            countyGradiculeField.name)

    for listedRow in bufferedCountyPolygonList:
        print str(listedRow)
        selectCounty = listedRow[1]

        whereClause = """ "COUNTY_NAME" = '""" + str(selectCounty) + """' """
        print "The whereClause is " + str(whereClause)
        SelectLayerByAttribute_management(bufferedCounties, "NEW_SELECTION",
                                          whereClause)

        SelectLayerByAttribute_management(loadedGradiculeCopy, "NEW_SELECTION",
                                          whereClause)

        Intersect_analysis([loadedGradiculeCopy, bufferedCounties],
                           tempCountyGradicule, "ALL")

        MultipartToSinglepart_management(tempCountyGradicule,
                                         tempCountyGradiculeSinglePart)

        # Selects the same county as the other Select, but does it from the miniBufferedCounties
        # so that the lines which lay inside of the county and running just along its edges
        # are erased, as they should only exist as gradicules for the counties adjoining this
        # one, but not for this one itself.
        SelectLayerByAttribute_management(miniBufferedCounties,
                                          "NEW_SELECTION", whereClause)

        MakeFeatureLayer_management(tempCountyGradiculeSinglePart,
                                    loadedTempGradicule)

        SelectLayerByAttribute_management(loadedTempGradicule, "NEW_SELECTION",
                                          whereClause)

        secVerGradiculeFields = ListFields(loadedTempGradicule)

        #for secVerGradiculeField in secVerGradiculeFields:
        #    print "A secVerGradiculeField was found: " + str(secVerGradiculeField.name)

        Erase_analysis(loadedTempGradicule, miniBufferedCounties,
                       tempCountyGradiculePostErase, xyToleranceVal)

        fieldsToCopy = [
            "SHAPE@", "County_Number", "County_Name", "DIRECTION", "COORD"
        ]

        # 2nd SearchCursor
        newCursor = daSearchCursor(tempCountyGradiculePostErase, fieldsToCopy)
        for newRow in newCursor:
            outputFeatureList.append(newRow)

        if 'newCursor' in locals():
            del newCursor
        else:
            pass

    try:
        Delete_management(countyGradiculeShortWithUser)
    except:
        pass

    CreateFeatureclass_management(sqlGdbLocation, countyGradiculeShortNoPath,
                                  "POLYLINE", "", "", "",
                                  spatialReferenceProjection)

    AddField_management(countyGradiculeShortNoPath, "County_Number", "DOUBLE",
                        "", "", "")

    AddField_management(countyGradiculeShortNoPath, "County_Name", "TEXT", "",
                        "", "55")

    AddField_management(countyGradiculeShortNoPath, "DIRECTION", "TEXT", "",
                        "", "5")

    AddField_management(countyGradiculeShortNoPath, "COORD", "TEXT", "", "",
                        "30")

    print "First Intersected County Gradicule Row: " + str(
        outputFeatureList[0])

    newCursor = daInsertCursor(countyGradiculeShortPath, fieldsToCopy)
    counter = 1
    for outputFeature in outputFeatureList:
        rowToInsert = ([outputFeature])

        insertedOID = newCursor.insertRow(outputFeature)

        counter += 1

        print "Inserted Row with Object ID of " + str(insertedOID)

    # Load the feature class. Remove anything shorter than 850 feet.
    MakeFeatureLayer_management(countyGradiculeShortPath,
                                loadedOutputGradicule)

    # Select the rows that have geometry which is shorter than 850 feet.
    ## Note that Shape.STLength() returns units in the projection
    ## or coordinate system that it the feature class is stored in.
    whereClause = """ Shape.STLength() <  850 """
    print "The whereClause is " + str(whereClause)
    SelectLayerByAttribute_management(loadedOutputGradicule, "NEW_SELECTION",
                                      whereClause)

    # If there is at least one row selected, delete each selected row.
    if int(GetCount_management(loadedOutputGradicule).getOutput(0)) > 0:
        print str(GetCount_management(loadedOutputGradicule).getOutput(
            0)) + "rows selected."
        DeleteRows_management(loadedOutputGradicule)
    else:
        print "No rows were selected to delete."

    if 'newCursor' in locals():
        del newCursor
    else:
        pass
def get_network_stations(networkCode, fc_name, spatialref, workspace="in_memory"):
    """
    Queries the AWDB to get a list of all stations by station triplet in the network
    specified. Then spawns get_stations() as a child process. get_stations retrieves
    the metadata of the stations, the records of which are placed into the stationQueue.
    As station records are returned, this function reads the records from the queue
    and writes them as features in a feature class created in the specified workspace.

    Requires: networkCode -- the code of the network to retrieve, i.e. SNTL
              fc_name -- the name of the fc to create in the specified workspace
              spatialref -- the spatial reference object to use for the fc

    Optional: workspace -- the workspace in which to create the fc
                           DEFAULT: "in_memory", the ArcGIS RAM workspace

    Returns: fc -- the result object from the CreateFeatureClass function
    """

    from arcpy import AddField_management, CreateFeatureclass_management
    from arcpy.da import InsertCursor

    LOGGER.info("\nGetting stations in the {0} network...".format(networkCode))
    # connect to the service definition
    client = Client(settings.WDSL_URL)
    # get list of station IDs in network
    stationIDs = client.service.getStations(networkCds=networkCode)
    numberofstations = len(stationIDs)
    LOGGER.log(
        15,
        "Found {0} stations in {1} network.".format(numberofstations,
                                                    networkCode)
    )

    # to pass back results from thread
    stationQueue = Queue()

    # create process to get station data
    getStationProcess = Process(target=get_stations,
                                args=(stationIDs, stationQueue))
    # start thread execution
    getStationProcess.start()

    LOGGER.info("Creating feature class in memory...")
    fc = CreateFeatureclass_management(
        workspace, fc_name, "POINT",
        has_z="ENABLED", spatial_reference=spatialref
    )

    LOGGER.info("Adding attribute fields to feature class...")
    for field in FIELDS:
        AddField_management(fc, **field)

    # tuple of fields to access with the insert cursor
    fieldsToAccess = (FIELDS[0]["field_name"],
                      FIELDS[1]["field_name"],
                      FIELDS[2]["field_name"],
                      "SHAPE@Z",
                      FIELDS[3]["field_name"],
                      FIELDS[4]["field_name"],
                      FIELDS[5]["field_name"],
                      FIELDS[6]["field_name"],
                      FIELDS[7]["field_name"],
                      "SHAPE@Y",
                      "SHAPE@X",
                      FIELDS[8]["field_name"],
                      FIELDS[9]["field_name"],
                      FIELDS[10]["field_name"],
                      FIELDS[11]["field_name"],
                      FIELDS[12]["field_name"],
                      FIELDS[13]["field_name"],
                      FIELDS[14]["field_name"],
                      FIELDS[15]["field_name"]
                      )

    countInserted = 0

    LOGGER.info("Writing stations to FC as data are returned from server...")

    # insert cursor to add records to fc
    with InsertCursor(fc, fieldsToAccess) as cursor:
        while True:
            station = stationQueue.get()  # get station data from queue

            if station == QUEUE_DONE:
                break

            try:
                if station[0] == MESSAGE_CODE:
                    LOGGER.log(station[1], station[2])
                    continue
            except KeyError:
                pass

            stationIDs.remove(station["stationTriplet"])

            cursor.insertRow((station[FIELDS[0]["field_name"]],
                              station[FIELDS[1]["field_name"]],
                              station[FIELDS[2]["field_name"]],
                              station["elevation"],
                              station[FIELDS[3]["field_name"]],
                              station[FIELDS[4]["field_name"]],
                              station[FIELDS[5]["field_name"]],
                              station[FIELDS[6]["field_name"]],
                              station[FIELDS[7]["field_name"]],
                              station["latitude"],
                              station["longitude"],
                              station[FIELDS[8]["field_name"]],
                              station[FIELDS[9]["field_name"]],
                              station[FIELDS[10]["field_name"]],
                              station[FIELDS[11]["field_name"]],
                              station[FIELDS[12]["field_name"]],
                              station[FIELDS[13]["field_name"]],
                              station[FIELDS[14]["field_name"]],
                              station[FIELDS[15]["field_name"]]
                              ))
            countInserted += 1

    LOGGER.info(
        "Successfully inserted {0} of {1} records into {2}.".format(
            countInserted, numberofstations, fc_name
        )
    )

    if countInserted != numberofstations:
        raise Exception("ERROR: Failed to get all stations for unknown reason.")

    return fc
def extendAndIntersectRoadFeatures(
    quarterOrHalf
):  # Place the operations that extend each road line segment by a certain distance here.
    # Should extend all the features that exist in the post-erase dataset. Might be more difficult
    # to calculate the angle of these lines accurately, but it should be easier to figure out
    # than trying to get the lines to split correctly with the buggy SplitLineAtPoint tool.

    if quarterOrHalf.lower() == "quarter":
        extensionLinesTextName = "createdExtensionLines_Q"
        createdExtensionLines = createdExtensionLines_Q
        # 9000 ft increase for _Q version.
        # Must be larger than the county bufferDistance (20000)
        extensionDistance = 31176
        extensionLinesTextName = "createdExtensionLines_Q"
        countyRoadNameRosette = countyRoadNameRosette_Q
        rosetteTextName = "countyRoadNameRosette_Q"
        tempRoadNameRosette = tempRoadNameRosette_Q
        tempRosetteTextName = "tempRoadNameRosette_Q"
        tempRoadNameRosetteSP = tempRoadNameRosetteSinglePoint_Q
        tempRosetteSPTextName = "tempRoadNameRosetteSinglePoint_Q"
        countyBorderFeature = countyBorderFeature_Q
    elif quarterOrHalf.lower() == "half":
        extensionLinesTextName = "createdExtensionLines_H"
        createdExtensionLines = createdExtensionLines_H
        # Must be larger than the county bufferDistance (11000)
        extensionDistance = 22176
        extensionLinesTextName = "createdExtensionLines_H"
        countyRoadNameRosette = countyRoadNameRosette_H
        rosetteTextName = "countyRoadNameRosette_H"
        tempRoadNameRosette = tempRoadNameRosette_H
        tempRosetteTextName = "tempRoadNameRosette_H"
        tempRoadNameRosetteSP = tempRoadNameRosetteSinglePoint_H
        tempRosetteSPTextName = "tempRoadNameRosetteSinglePoint_H"
        countyBorderFeature = countyBorderFeature_H
    else:
        print "quarterOrHalf variable not correctly defined."
        raise (Exception("quarterOrHalf value error."))

    print "Starting to extend and intersect road features."

    if Exists(createdExtensionLines):
        Delete_management(createdExtensionLines)
    else:
        pass

    CreateFeatureclass_management(inMemGDB, extensionLinesTextName, "POLYLINE",
                                  "", "", "", spatialReferenceProjection)

    # Add a column for roadname called roadNameForSplit.
    AddField_management(createdExtensionLines, "roadNameForSplit", "TEXT", "",
                        "", "55")

    # Add a column which stores the angle to display a label called called LabelAngle.
    AddField_management(createdExtensionLines, "LabelAngle", "DOUBLE", "", "",
                        "")  # Change to double.

    # Add a column which stores the County Number.
    AddField_management(createdExtensionLines, "County_Number", "DOUBLE", "",
                        "", "")

    roadLinesToInsertList = list()

    roadLinesList = getRoadLinesList()

    for roadLinesItem in roadLinesList:

        roadNameToUse = roadLinesItem[2]
        countyNumber = roadLinesItem[3]

        linePointsArray = ArcgisArray()

        firstPointTuple = (roadLinesItem[1].firstPoint.X,
                           roadLinesItem[1].firstPoint.Y)
        lastPointTuple = (roadLinesItem[1].lastPoint.X,
                          roadLinesItem[1].lastPoint.Y)

        # Make this a two-step process.
        # Might be as simple as
        # adding _1 to the end of the first set of variables,
        # adding _2 to the end of the second set of variables,
        # then making the extensions in both directions
        # and creating a new line that has the endpoints
        # from both sides as it's first and last point.
        # if necessary, could add the other points in between
        # but probably not necessary just for generating
        # an intersection point.

        yValue_1 = -(lastPointTuple[1] - firstPointTuple[1]
                     )  # made y value negative
        xValue_1 = lastPointTuple[0] - firstPointTuple[0]

        lineDirectionAngle_1 = math.degrees(math.atan2(
            xValue_1, yValue_1))  # reversed x and y

        lineDirectionAngle_1 = -(((lineDirectionAngle_1 + 180) % 360) - 180
                                 )  # correction for certain quadrants
        #print "lineDirectionAngle: " + str(lineDirectionAngle_1)

        origin_x_1 = firstPointTuple[0]
        origin_y_1 = firstPointTuple[1]

        yValue_2 = -(firstPointTuple[1] - lastPointTuple[1]
                     )  # made y value negative
        xValue_2 = firstPointTuple[0] - lastPointTuple[0]

        lineDirectionAngle_2 = math.degrees(math.atan2(
            xValue_2, yValue_2))  # reversed x and y

        lineDirectionAngle_2 = -(((lineDirectionAngle_2 + 180) % 360) - 180
                                 )  # correction for certain quadrants
        #print "lineDirectionAngle: " + str(lineDirectionAngle_2)

        origin_x_2 = lastPointTuple[0]
        origin_y_2 = lastPointTuple[1]

        (disp_x_1, disp_y_1) = (extensionDistance *
                                math.sin(math.radians(lineDirectionAngle_1)),
                                extensionDistance *
                                math.cos(math.radians(lineDirectionAngle_1)))

        (end_x_1, end_y_1) = (origin_x_1 + disp_x_1, origin_y_1 + disp_y_1)

        (disp_x_2, disp_y_2) = (extensionDistance *
                                math.sin(math.radians(lineDirectionAngle_2)),
                                extensionDistance *
                                math.cos(math.radians(lineDirectionAngle_2)))

        (end_x_2, end_y_2) = (origin_x_2 + disp_x_2, origin_y_2 + disp_y_2)

        startPoint = ArcgisPoint()
        endPoint = ArcgisPoint()

        startPoint.ID = 0
        startPoint.X = end_x_1
        startPoint.Y = end_y_1

        endPoint.ID = 1
        endPoint.X = end_x_2
        endPoint.Y = end_y_2

        linePointsArray.add(startPoint)
        linePointsArray.add(endPoint)

        newLineFeature = ArcgisPolyLine(linePointsArray)

        # Need to create an extension for both ends of the line and add them
        # to the array.

        #newLineFeature = createdExtensionLinesCursor.newRow()

        #newLineFeature.SHAPE = linePointsArray

        lineDirectionOutput = "0"

        if lineDirectionAngle_1 > 0:
            lineDirectionOutput = lineDirectionAngle_1
        elif lineDirectionAngle_2 > 0:
            lineDirectionOutput = lineDirectionAngle_2
        else:
            pass

        roadLinesToInsertList.append(
            [newLineFeature, roadNameToUse, lineDirectionOutput, countyNumber])

        #createdExtensionLinesCursor.insertRow([newLineFeature, roadNameToUse, lineDirectionOutput])

        if "newLineFeature" in locals():
            del newLineFeature
        else:
            pass

    # Consider building this as a separate list and then just looping
    # through the list to put it into the cursor instead
    # of doing logic and inserting into the cursor at the same place.

    #start editing session
    #newEditingSession = daEditor(sqlGdbLocation)
    #newEditingSession.startEditing()
    #newEditingSession.startOperation()

    createdExtensionLinesCursor = daInsertCursor(
        createdExtensionLines,
        ["SHAPE@", "roadNameForSplit", "LabelAngle", "County_Number"])

    for roadLinesToInsertItem in roadLinesToInsertList:
        createdExtensionLinesCursor.insertRow(roadLinesToInsertItem)

    # End editing session
    #newEditingSession.stopOperation()
    #newEditingSession.stopEditing(True)

    if "createdExtensionLinesCursor" in locals():
        del createdExtensionLinesCursor
    else:
        pass

    # Remove the previous countyRoadNameRosette so that it can be recreated.
    if Exists(rosetteTextName):
        Delete_management(rosetteTextName)
    else:
        pass

    CreateFeatureclass_management(sqlGdbLocation, rosetteTextName, "POINT", "",
                                  "", "", spatialReferenceProjection)

    AddField_management(countyRoadNameRosette, "roadNameForSplit", "TEXT", "",
                        "", "55")

    AddField_management(countyRoadNameRosette, "LabelAngle", "DOUBLE", "", "",
                        "")  # Change to double.

    AddField_management(countyRoadNameRosette, "County_Number", "DOUBLE", "",
                        "", "")

    AddField_management(countyRoadNameRosette, "COUNTY_NAME", "TEXT", "", "",
                        "55")

    # Now then, need to check for the existence
    # of and delete the point intersection layer
    # if it exists.

    # Then, recreate it and the proper fields.

    inMemoryCountyBorderExtension = "aCountyBorderExtensionBuffer"
    inMemoryExtensionLines = "aLoadedExtensionLines"

    try:
        Delete_management(inMemoryCountyBorderExtension)
    except:
        pass

    try:
        Delete_management(inMemoryExtensionLines)
    except:
        pass

    # Temporary layer, use CopyFeatures_management to persist to disk.
    MakeFeatureLayer_management(
        countyBorderFeature,
        inMemoryCountyBorderExtension)  # County Border extension feature

    # Temporary layer, use CopyFeatures_management to persist to disk.
    MakeFeatureLayer_management(
        createdExtensionLines,
        inMemoryExtensionLines)  # Line extension feature

    borderFeatureList = getBorderFeatureList(quarterOrHalf)

    borderFeatureList = sorted(borderFeatureList,
                               key=lambda feature: feature[3])

    for borderFeature in borderFeatureList:
        borderFeatureName = borderFeature[2]
        borderFeatureNumber = borderFeature[3]
        print "borderFeatureName: " + str(
            borderFeatureName) + " & borderFeatureNumber: " + str(
                int(borderFeatureNumber))

        countyBorderWhereClause = ' "COUNTY_NUMBER" = ' + str(
            int(borderFeatureNumber)) + ' '

        SelectLayerByAttribute_management(inMemoryCountyBorderExtension,
                                          "NEW_SELECTION",
                                          countyBorderWhereClause)

        countyBorderSelectionCount = GetCount_management(
            inMemoryCountyBorderExtension)

        print "County Borders Selected: " + str(countyBorderSelectionCount)

        # Had to single-quote the borderFeatureNumber because it is stored as a string in the table.
        # Unsingle quoted because it was changed to a float.
        extensionLinesWhereClause = ' "COUNTY_NUMBER" = ' + str(
            int(borderFeatureNumber)) + ' '

        SelectLayerByAttribute_management(inMemoryExtensionLines,
                                          "NEW_SELECTION",
                                          extensionLinesWhereClause)

        extensionLineSelectionCount = GetCount_management(
            inMemoryExtensionLines)

        print "Extension Lines Selected: " + str(extensionLineSelectionCount)

        if Exists(tempRosetteTextName):
            Delete_management(tempRosetteTextName)
        else:
            pass

        if Exists(tempRosetteSPTextName):
            Delete_management(tempRosetteSPTextName)
        else:
            pass

        Intersect_analysis(
            [inMemoryCountyBorderExtension, inMemoryExtensionLines],
            tempRoadNameRosette, "ALL", "", "POINT")

        # Intersect to an output temp layer.

        # Next, need to loop through all of the counties.

        # Get the county number and use it to select
        # a county extension buffer in the county
        # extension buffers layer.

        # Then, use the county number to select
        # all of the lines for that county
        # in the extension lines layer.

        # Then, export those to a temp layer in the fgdb.

        # Change multipoint to singlepoint.

        # Was working until I moved from gisprod to sdedev for the data source.
        # not sure why. Check to make sure projections match.
        # ^ Fixed.

        try:

            # Run the tool to create a new fc with only singlepart features
            MultipartToSinglepart_management(tempRoadNameRosette,
                                             tempRoadNameRosetteSP)

            # Check if there is a different number of features in the output
            #   than there was in the input
            inCount = int(
                GetCount_management(tempRoadNameRosette).getOutput(0))
            outCount = int(
                GetCount_management(tempRoadNameRosetteSP).getOutput(0))

            if inCount != outCount:
                print "Found " + str(outCount -
                                     inCount) + " multipart features."
                #print "inCount, including multipart = " + str(inCount)
                #print "outCount, singlepart only = " + str(outCount)

            else:
                print "No multipart features were found"

        except ExecuteError:
            print GetMessages()
        except Exception as e:
            print e

        print "Appending the temp point layer to the county point intersection layer."

        Append_management([tempRoadNameRosetteSP], countyRoadNameRosette,
                          "NO_TEST")

        # K, worked correctly. Just need to change LabelAngle to a float and it might be what
        # I want.

        print "Done adding points to the countyRoadNameRosette feature class."
def createCountyLinesForEachCounty():

    env.workspace = sqlGdbLocation

    inputCountyLines = sharedCountyLines
    inputCountyPolygons = sharedCounties
    dissolvedCountyLines = countyLinesDissolved
    loadedCounties = 'loadedCounties'
    tempCountyLines = r'in_memory\tempCountyLines'
    outputCountyLines = countyLinesIntersectedNoPath
    bufferCursorFields = ["OBJECTID"]

    # Dissolve all of those county lines into one set of lines
    # then, need to create 105 features that are are intersected
    # with the polygons from said line dissolve.

    Dissolve_management(inputCountyLines, dissolvedCountyLines)
    Buffer_analysis(inputCountyPolygons, countiesBuffered, "15500 Feet")

    bufferedCountyPolygonList = list()
    outputFeatureList = list()

    # 1st SearchCursor
    newCursor = daSearchCursor(countiesBuffered, bufferCursorFields)
    for newRow in newCursor:
        bufferedCountyPolygonList.append(list(newRow))

    if 'newCursor' in locals():
        del newCursor
    else:
        pass

    MakeFeatureLayer_management(countiesBuffered, loadedCounties)

    loadedCountiesFields = ListFields(loadedCounties)

    for loadedCountiesField in loadedCountiesFields:
        print "A loadedCountiesField was found: " + str(
            loadedCountiesField.name)

    for listedRow in bufferedCountyPolygonList:
        selectNumber = listedRow[0]

        whereClause = """ "OBJECTID" = """ + str(selectNumber)
        print "The whereClause = " + str(whereClause)
        SelectLayerByAttribute_management(loadedCounties, "NEW_SELECTION",
                                          whereClause)

        Intersect_analysis([dissolvedCountyLines, loadedCounties],
                           tempCountyLines, "ALL")

        # 2nd SearchCursor
        newCursor = daSearchCursor(tempCountyLines,
                                   ["SHAPE@", "County_Number", "County_Name"])
        for newRow in newCursor:
            outputFeatureList.append(newRow)

        if 'newCursor' in locals():
            del newCursor
        else:
            pass

    try:
        Delete_management(countyLinesIntersectedWithUser)
    except:
        pass

    CreateFeatureclass_management(sqlGdbLocation, outputCountyLines,
                                  "POLYLINE", "", "", "",
                                  spatialReferenceProjection)

    AddField_management(outputCountyLines, "County_Number", "DOUBLE", "", "",
                        "")

    AddField_management(outputCountyLines, "County_Name", "TEXT", "", "", "55")

    print "First Intersected County Row: " + str(outputFeatureList[0])

    countyLinesIntersectFields = ["SHAPE@", "County_Number", "County_Name"]

    newCursor = daInsertCursor(countyLinesIntersectedPath,
                               countyLinesIntersectFields)
    counter = 1
    for outputFeature in outputFeatureList:
        rowToInsert = ([outputFeature])

        insertedOID = newCursor.insertRow(outputFeature)

        counter += 1

        print "Inserted Row with Object ID of " + str(insertedOID)

    if 'newCursor' in locals():
        del newCursor
    else:
        pass
Example #7
0
def GdbCreate():
    CreateFileGDB_management(workspace, gdbname)
    CreateFeatureclass_management(gdb, 'Crossings', 'POINT', '#', 'DISABLED', 'ENABLED', spatialCRS)
Example #8
0
try:
    # My workspace
    env.workspace = "C:\\learnPython\\data"

    # Template shapefile
    template = "Precip2008Readings.shp"

    # List with years: 2009, 2010, 2011 and 2012
    for year in range(2009, 2013):

        # Name for new file
        newfile = "Precip" + str(year) + "Readings.shp"

        # Create four empty copies of file tamplate Precip2008Readings.shp
        CreateFeatureclass_management(env.workspace, newfile, "POINT",
                                      template, "DISABLED", "DISABLED",
                                      template)
# If happen some error
except:
    # Show messages for error
    print GetMessages()

# ------------------ Practice 5 - Clip all feature classes in a geodatabase ---------------------
from arcpy import env, AddMessage, Clip_analysis, ListFeatureClasses

# Create directors files
usa_workspace = "C:\\learnPython\\data\\USA.gdb"
iowa_data = "C:\\learnPython\\data\\Iowa.gdb\\Iowa"

# Get a list of all feature classes in the USA folder
env.workspace = usa_workspace
in_table = GetParameterAsText(0)  # Feature Layer
friendly_value = GetParameterAsText(1)  # Integer
output = GetParameterAsText(2)  # Feature Layer

# Get data from input-table
where_clause = '{0} = 1'.format(friendly_value)
field_names = ['SHAPE@XY', 'Type']
rows = list()
with SearchCursor(in_table, field_names, where_clause) as sc:
    for row in sc:
        rows.append(row)

# Create new feature class
path = '\\'.join(in_table.split('\\')[:-1])
output_name = output.split('\\')[-1]
CreateFeatureclass_management(path, output_name, 'POINT')

# Add fields to the new feature class
fields = [
    ('Type', 'TEXT'),
    ('Friendly', 'SHORT')
]
for f in fields:
    AddField_management(output, f[0], f[1])

# Write rows to the table
AddMessage(os.path.join(path, in_table))
with InsertCursor(output, field_names) as icursor:
    for row in rows:
        icursor.insertRow(row)
adj_dbf_name = ("%s_%s_%s_%s_%s_%s.dbf" % (ADJACENCY_LIST_NAME,
    basename(inputs[INPUT_BUILDINGS]), basename(inputs[INPUT_NETWORK]),
    inputs[ID_ATTRIBUTE], inputs[IMPEDANCE_ATTRIBUTE],
    inputs[ACCUMULATOR_ATTRIBUTES])).replace("#", "None")
if len(adj_dbf_name) > MAX_FILE_NAME_LENGTH:
  AddWarning(WARNING_LARGE_ADJ_FILE_NAME)
adj_dbf = join(inputs[OUTPUT_LOCATION], adj_dbf_name)

# Output file names
output_feature_class_name = feature_class_name(inputs[OUTPUT_FILE_NAME])
output_feature_class = "%s.shp" % join(inputs[OUTPUT_LOCATION],
    output_feature_class_name)
# Create a feature class that is a copy of the input buildings
try:
  AddMessage(INPUT_BUILDINGS_COPY_STARTED)
  CreateFeatureclass_management(out_path=inputs[OUTPUT_LOCATION],
      out_name=output_feature_class_name)
  CopyFeatures_management(in_features=inputs[INPUT_BUILDINGS],
      out_feature_class=output_feature_class)
  AddMessage(INPUT_BUILDINGS_COPY_FINISHED)
except:
  AddWarning(GetMessages(2))
  AddMessage(INPUT_BUILDINGS_COPY_FAILED)
  success = False
output_layer_name = layer_name(inputs[OUTPUT_FILE_NAME])
output_layer = "%s.lyr" % join(inputs[OUTPUT_LOCATION], output_layer_name)

# If output has already been created, don't carry on
if Exists(output_layer):
  AddWarning(WARNING_OUTPUT_ALREADY_EXISTS)
  success = False
Example #11
0
def main():
    fc = GetParameterAsText(0)
    out_table = GetParameterAsText(1)
    out_fc = GetParameterAsText(2)

    for thingy in [out_table, out_fc]:
        if Exists(thingy):
            Delete_management(thingy)

    # --------------set up reporting table for new field names-----------------
    field_name = "PRENAME"
    field_count = "NEWCOUNT"
    schema_count = "PRECOUNT"
    new_name = "NEWNAME"

    #see if the output table exists
    if not Exists(out_table):
        CreateTable_management(dirname(out_table), basename(out_table))
    else:
        DeleteRows_management(out_table)

    #see if fields already exist, if not, create them
    if not fieldExists(out_table, field_name):
        AddField_management(out_table, field_name, "TEXT", "", "", 30)

    if not fieldExists(out_table, schema_count):
        AddField_management(out_table, schema_count, "LONG")

    if not fieldExists(out_table, field_count):
        AddField_management(out_table, field_count, "SHORT")

    if not fieldExists(out_table, new_name):
        AddField_management(out_table, new_name, "TEXT", "", "", 10)

    # loop through all fields
    all_fields = ListFields(fc)

    # create name dictionary of shortened shapefile names
    name_dictionary = {}
    shortList = []  # necessary for flagging repeated field names

    for fn in all_fields:
        short_name = fn.name
        if len(fn.name) > 10:
            short_name = fn.name[0:10]

        # make sure the shortened field name doesn't already exists
        if short_name not in shortList:
            shortList.append(short_name)
            name_dictionary[fn.name] = short_name
        else:
            i = 0
            while short_name in shortList and i < 100:
                short_name = short_name[0:7] + "_" + str(i)
                i += 1
            name_dictionary[fn.name] = short_name
            shortList.append(short_name)

    # -----next step, create new feature class & add all fields----------------
    # -----for text fields, make the length the proper length------------------

    desc = Describe(fc)
    geom_type = desc.shapeType
    SR = desc.spatialReference

    # create new feature class
    CreateFeatureclass_management(dirname(out_fc), basename(out_fc), geom_type,
                                  "", "", "", SR)

    # create list to hold the names of number fields (used later)
    numFields = []
    dateFields = []

    # get the name of the OID field while looping
    oid = ""

    # loop through string fields
    for f in all_fields:
        short_name = name_dictionary[f.name]
        data_type = f.type.upper()

        # check to see if the data type is "normal"
        if data_type in [
                "TEXT", "FLOAT", "DOUBLE", "SHORT", "LONG", "DATE", "BLOB",
                "RASTER", "GUID", "STRING", "INTEGER", "SMALLINTEGER"
        ]:

            # special track for string fields
            if data_type in ["STRING", "TEXT"]:

                # set counter at 0
                i = 0

                # set up search cursor on feature class just on that field
                with SearchCursor(fc, (f.name)) as rows:
                    for row in rows:
                        if row[0] is not None:
                            # loop through values to get the longest length
                            if len(row[0]) > i:
                                i = len(row[0])

                # make sure i isn't bigger than 254
                if i > 254:
                    i = 254

                # at this point, i equals the length of the longest field entry

                # insert the field name and the length into the output table
                cursor = InsertCursor(
                    out_table,
                    (field_name, field_count, schema_count, new_name))
                new_row = (f.name, i, f.length, short_name)
                cursor.insertRow(new_row)

                del row, rows, cursor, new_row

                # add a row to the new feature class
                AddField_management(out_fc, short_name, "TEXT", "", "", i)

            # track for numbers, GUIDs & dates
            else:
                AddField_management(out_fc, short_name, data_type)

                # if it's a number, record the field name in the num field list
                if data_type in [
                        "SHORT", "LONG", "INTEGER", "FLOAT", "DOUBLE"
                ]:
                    numFields.append(f.name)
                elif data_type in ["DATE"]:
                    dateFields.append(f.name)

                #make sure all fields are in the translation table
                cursor = InsertCursor(out_table, (field_name, new_name))
                new_row = (f.name, short_name)
                cursor.insertRow(new_row)
                del cursor, new_row

        elif data_type == "OID":
            AddField_management(out_fc, "LinkOID", "INTEGER")
            name_dictionary[f.name] = "LinkOID"  # add for field mapping
            oid = f.name

            # add link field for object ID to the mapping table
            cursor = InsertCursor(out_table, (field_name, new_name))
            new_row = (f.name, "LinkOID")
            cursor.insertRow(new_row)
            del cursor, new_row
        elif data_type == "GEOMETRY":
            pass
        else:
            print("Field " + f.name + " is type " + f.type +
                  ". It will not be copied over.")
            AddWarning("Field " + f.name + " is type " + f.type +
                       ". It will not be copied over.")
            del name_dictionary[f.name]

    # -----copy data into the new FC-------------------------------------------

    # set up field lists for search & insert cursors
    oldFields, newFields = [], []

    for field in name_dictionary.keys():
        oldFields.append(field)
        newFields.append(name_dictionary[field])

    # set up a text only version of the fields
    oldFieldsTextOnly = tuple(oldFields)
    newFieldsTextOnly = tuple(newFields)

    # add SHAPE to the original set of fields
    oldFields.append("SHAPE@")
    newFields.append("SHAPE@")

    # convert the new field list to a tuple, safety first
    newFields = tuple(newFields)  # this is the one with the shape field

    # create a list of the indexes of number & date fields
    numFieldsIndexList, dateFieldsIndexList = [], []
    for numF in numFields:
        numFieldsIndexList.append(oldFields.index(numF))
    for dateF in dateFields:
        dateFieldsIndexList.append(oldFields.index(dateF))

    # ran into an issue with invalid geometry, so here's the workaround
    invalidDict = {"point": 1, "polyline": 2, "polygon": 3}

    # set up reporting for records that didn't copy
    didNotCopy = []

    # fill new rows with old rows
    with SearchCursor(fc, oldFields) as rows:
        for row in rows:
            geomIndex = oldFields.index("SHAPE@")
            geom = row[geomIndex]
            objectID = str(row[oldFields.index(oid)])
            try:

                try:
                    # find the minimum number of required points
                    minNum = invalidDict[geom_type.lower()]

                    # get the count of points in the geometry
                    count = geom.pointCount

                    # if the count is smaller than the minimum number, there's a problem
                    if count < minNum:
                        wc = oid + " = " + objectID
                        # here, we won't copy the geometry, only the fields
                        userMessage("count smaller than min")
                        with SearchCursor(fc, oldFieldsTextOnly, wc) as rows2:
                            for row2 in rows2:
                                makeRow(out_fc, newFieldsTextOnly, row2,
                                        numFieldsIndexList,
                                        dateFieldsIndexList)
                        del row2, rows2, wc

                    else:
                        # excellent, the record is normal & will copy
                        makeRow(out_fc, newFields, row, numFieldsIndexList,
                                dateFieldsIndexList)

                except Exception as e:
                    userMessage(str(e))
                    # if we're in this area, it means the record has no geometry
                    wc = oid + " = " + objectID
                    with SearchCursor(fc, oldFieldsTextOnly, wc) as rows2:
                        for row2 in rows2:
                            makeRow(out_fc, newFieldsTextOnly, row2,
                                    numFieldsIndexList, dateFieldsIndexList)
                    del row2, rows2, wc

            except Exception as e:
                userMessage(str(e))
                # for whatever reason, the record did not copy
                userMessage("Error copying record ObjectID " + objectID)
                didNotCopy.append(objectID)

    if didNotCopy != []:
        userMessage("These records did not copy- %s %s" %
                    (oid, ", ".join(didNotCopy)))

    userMessage("Skinny shapefile complete.")
Example #12
0
out_rid = ['ROUTEID', 'TEXT']
out_from = ['FROM_M', 'DOUBLE']
out_to = ['TO_M', 'DOUBLE']
out_dist_st = ['STA_DIST', 'DOUBLE']
out_dist_end = ['END_DIST', 'DOUBLE']
field_definition = [out_rid, out_from, out_to, out_dist_end, out_dist_st]

field_names = [field[0] for field in field_definition]
field_names_shapes = field_names
field_names_shapes.append('SHAPE@')
Network_SpatRef = Describe(Network).spatialReference

# Create an empty feature class for storing all the line segment
CreateFeatureclass_management(env.scratchGDB,
                              OutputLine,
                              geometry_type='POLYLINE',
                              spatial_reference=Network_SpatRef)
env.overwriteOutput = True  # Allow overwrite the output

for field in field_definition:
    field_name = field[0]  # Field name
    field_type = field[1]  # Field type
    # Create all the necessary field for the line feature class
    AddField_management(env.scratchGDB + '/' + OutputLine, field_name,
                        field_type)

# The insert cursor for line feature class
line_ins = da.InsertCursor(env.scratchGDB + '/' + OutputLine,
                           field_names_shapes)

with da.SearchCursor(POK_Table,
def main():
  """
  Runs the centrality tool.
  """
  env.overwriteOutput = True # Enable overwritting
  CheckOutExtension("Network")

  # Success of the program through the six steps
  success = True

  # Inputs to the tool
  if len(argv) != INPUT_COUNT + 1:
    raise Exception("Invalid number of inputs")
  input_number = index()
  input_number.next() # Skip over sys.argv[0]
  inputs = {}
  inputs[INPUT_BUILDINGS] = argv[input_number.next()]
  inputs[POINT_LOCATION] = ("INSIDE" if argv[input_number.next()] == "true" else
      "CENTROID")
  inputs[INPUT_NETWORK] = argv[input_number.next()]
  inputs[COMPUTE_REACH] = argv[input_number.next()] == "true"
  inputs[COMPUTE_GRAVITY] = argv[input_number.next()] == "true"
  inputs[COMPUTE_BETWEENNESS] = argv[input_number.next()] == "true"
  inputs[COMPUTE_CLOSENESS] = argv[input_number.next()] == "true"
  inputs[COMPUTE_STRAIGHTNESS] = argv[input_number.next()] == "true"
  inputs[ID_ATTRIBUTE] = argv[input_number.next()]
  inputs[NODE_WEIGHT_ATTRIBUTE] = argv[input_number.next()]
  inputs[IMPEDANCE_ATTRIBUTE] = argv[input_number.next()]
  try: inputs[SEARCH_RADIUS] = float(argv[input_number.next()])
  except: inputs[SEARCH_RADIUS] = INFINITE_RADIUS
  inputs[USE_NETWORK_RADIUS] = (argv[input_number.next()] ==
      ON_THE_NETWORK_OPTION)
  try: inputs[BETA] = float(argv[input_number.next()])
  except: raise Invalid_Input_Exception("Beta")
  inputs[NORMALIZE_RESULTS] = [measure for measure in
      argv[input_number.next()].split(";") if measure != "#"]
  inputs[OUTPUT_LOCATION] = argv[input_number.next()]
  inputs[OUTPUT_FILE_NAME] = argv[input_number.next()]
  inputs[ACCUMULATOR_ATTRIBUTES] = argv[input_number.next()]

  # Record the origin nodes for centrality measurements
  # This is important if the user selects a subset of the features to be origins
  selected_features = all_values_in_column(inputs[INPUT_BUILDINGS],
    inputs[ID_ATTRIBUTE])
  # Clear selection if we got a layer file
  try:
    SelectLayerByAttribute_management(inputs[INPUT_BUILDINGS],
      "CLEAR_SELECTION")
  except:
    pass

  # Adjacency List table name
  node_locations_needed = (inputs[COMPUTE_STRAIGHTNESS] or
      not inputs[USE_NETWORK_RADIUS])
  adj_dbf_name = ("%s_%s_%s_%s_%s_%s.dbf" % (ADJACENCY_LIST_NAME,
      basename(inputs[INPUT_BUILDINGS]), basename(inputs[INPUT_NETWORK]),
      inputs[ID_ATTRIBUTE], inputs[IMPEDANCE_ATTRIBUTE],
      inputs[ACCUMULATOR_ATTRIBUTES])).replace("#", "None")
  if len(adj_dbf_name) > MAX_FILE_NAME_LENGTH:
    AddWarning(WARNING_LARGE_ADJ_FILE_NAME)
  adj_dbf = join(inputs[OUTPUT_LOCATION], adj_dbf_name)

  # Output file names
  output_feature_class_name = feature_class_name(inputs[OUTPUT_FILE_NAME])
  output_feature_class = "%s.shp" % join(inputs[OUTPUT_LOCATION],
      output_feature_class_name)
  # Create a feature class that is a copy of the input buildings
  try:
    AddMessage(INPUT_BUILDINGS_COPY_STARTED)
    CreateFeatureclass_management(out_path=inputs[OUTPUT_LOCATION],
        out_name=output_feature_class_name)
    CopyFeatures_management(in_features=inputs[INPUT_BUILDINGS],
        out_feature_class=output_feature_class)
    AddMessage(INPUT_BUILDINGS_COPY_FINISHED)
  except:
    AddWarning(GetMessages(2))
    AddMessage(INPUT_BUILDINGS_COPY_FAILED)
    success = False
  output_layer_name = layer_name(inputs[OUTPUT_FILE_NAME])
  output_layer = "%s.lyr" % join(inputs[OUTPUT_LOCATION], output_layer_name)

  # If output has already been created, don't carry on
  if Exists(output_layer):
    AddWarning(WARNING_OUTPUT_ALREADY_EXISTS)
    success = False

  # We will convert polygon input buildings to point feature class
  buildings_description = Describe(output_feature_class)
  if buildings_description.shapeType == "Point":
    # Input buildings are already a point shape file
    inputs[INPUT_POINTS] = output_feature_class
  elif buildings_description.shapeType == "Polygon":
    # Input buildings need to be converted to point feature class
    point_feature_class_name = POINT_FEATURE_CLASS_NAME(
        basename(output_feature_class), inputs[POINT_LOCATION])
    inputs[INPUT_POINTS] = "%s.shp" % join(inputs[OUTPUT_LOCATION],
        point_feature_class_name)
    # If FID is used as ID attribute, we need to change it since a point
    #     shapefile will be in use
    if inputs[ID_ATTRIBUTE] == "FID":
      inputs[ID_ATTRIBUTE] = ORIGINAL_FID
  else:
    # Input buildings need to be either points or polygons
    raise Invalid_Input_Exception("Input Buildings")

  # Find the appropriate symbology layer
  for metric_index in range(len(METRICS)):
      if inputs[COMPUTE_REACH + metric_index]:
          first_metric = METRICS[metric_index]
          break
  symbology_layer_name = get_symbology_layer_name(
      buildings_description.shapeType, first_metric)
  symbology_layer = join(SYMBOLOGY_DIR, symbology_layer_name)

  def clean_up():
    """
    Removes all auxiliary files
    """
    auxiliary_dir = join(inputs[OUTPUT_LOCATION], AUXILIARY_DIR_NAME)
    od_cost_matrix_layer = join(auxiliary_dir, OD_COST_MATRIX_LAYER_NAME)
    od_cost_matrix_lines = join(auxiliary_dir, OD_COST_MATRIX_LINES)
    temp_adj_dbf_name = "%s~.dbf" % adj_dbf_name[-4]
    temp_adj_dbf = join(inputs[OUTPUT_LOCATION], temp_adj_dbf_name)
    partial_adj_dbf = join(auxiliary_dir, PARTIAL_ADJACENCY_LIST_NAME)
    polygons = join(auxiliary_dir, POLYGONS_SHAPEFILE_NAME)
    raster = join(auxiliary_dir, RASTER_NAME)
    polygons_layer = join(auxiliary_dir, POLYGONS_LAYER_NAME)
    input_points_layer = join(auxiliary_dir, INPUT_POINTS_LAYER_NAME)
    for delete_path in [input_points_layer, polygons_layer, raster, polygons,
        partial_adj_dbf, temp_adj_dbf, od_cost_matrix_lines,
        od_cost_matrix_layer, auxiliary_dir]:
      delete(delete_path)

  try:
    """
    Here we carry out the six steps of the tool
    """
    # Step 1
    if success:
      AddMessage(STEP_1_STARTED)
      # If necessary, convert input buildings to point feature class
      if buildings_description.shapeType == "Polygon":
        AddMessage(POINT_CONVERSION_STARTED)
        to_point_feature_class(output_feature_class, inputs[INPUT_POINTS],
            inputs[POINT_LOCATION])
        AddMessage(POINT_CONVERSION_FINISHED)
      if Exists(adj_dbf):
        AddMessage(ADJACENCY_LIST_COMPUTED)
        if node_locations_needed:
          calculate_network_locations(inputs[INPUT_POINTS],
              inputs[INPUT_NETWORK])
        AddMessage(STEP_1_FINISHED)
      else:
        try:
          compute_adjacency_list(inputs[INPUT_POINTS], inputs[INPUT_NETWORK],
              inputs[ID_ATTRIBUTE], inputs[IMPEDANCE_ATTRIBUTE],
              inputs[ACCUMULATOR_ATTRIBUTES], inputs[SEARCH_RADIUS],
              inputs[OUTPUT_LOCATION], adj_dbf_name)
          AddMessage(STEP_1_FINISHED)
        except:
          AddWarning(GetMessages(2))
          AddMessage(STEP_1_FAILED)
          success = False

    # Step 2
    if success:
      AddMessage(STEP_2_STARTED)
      try:
        distance_field = trim("Total_%s" % inputs[IMPEDANCE_ATTRIBUTE])
        accumulator_fields = set([trim("Total_%s" % accumulator_attribute)
            for accumulator_attribute in inputs[ACCUMULATOR_ATTRIBUTES].split(
            ";") if accumulator_attribute != "#"])
        # Graph representation: dictionary mapping node id's to Node objects
        nodes = {}
        # The number of rows in |adj_dbf|
        directed_edge_count = int(GetCount_management(adj_dbf).getOutput(0))
        graph_progress = Progress_Bar(directed_edge_count, 1, STEP_2)
        rows = UpdateCursor(adj_dbf)
        for row in rows:
          # Get neighboring nodes, and the distance between them
          origin_id = row.getValue(trim(ORIGIN_ID_FIELD_NAME))
          destination_id = row.getValue(trim(DESTINATION_ID_FIELD_NAME))
          distance = float(row.getValue(distance_field))
          # Make sure the nodes are recorded in the graph
          for id in [origin_id, destination_id]:
            if not id in nodes:
              nodes[id] = Node()
          # Make sure that the nodes are neighbors in the graph
          if origin_id != destination_id and distance >= 0:
            accumulations = {}
            for field in accumulator_fields:
              accumulations[field] = float(row.getValue(field))
            nodes[origin_id].add_neighbor(destination_id, distance,
              accumulations)
            nodes[destination_id].add_neighbor(origin_id, distance,
              accumulations)
          graph_progress.step()
        N = len(nodes) # The number of nodes in the graph
        if N == 0:
          AddWarning(WARNING_NO_NODES)
          success = False
        AddMessage(STEP_2_FINISHED)
      except:
        AddWarning(GetMessages(2))
        AddMessage(STEP_2_FAILED)
        success = False

    # Step 3
    if success:
      AddMessage(STEP_3_STARTED)
      try:
        get_weights = inputs[NODE_WEIGHT_ATTRIBUTE] != "#"
        get_locations = node_locations_needed
        # Keep track of number nodes in input points not present in the graph
        point_not_in_graph_count = 0
        input_point_count = int(
            GetCount_management(inputs[INPUT_POINTS]).getOutput(0))
        node_attribute_progress = Progress_Bar(input_point_count, 1, STEP_3)
        rows = UpdateCursor(inputs[INPUT_POINTS])
        for row in rows:
          id = row.getValue(inputs[ID_ATTRIBUTE])
          if not id in nodes:
            point_not_in_graph_count += 1
            continue
          if get_weights:
            setattr(nodes[id], WEIGHT,
                row.getValue(trim(inputs[NODE_WEIGHT_ATTRIBUTE])))
          if get_locations:
            snap_x = row.getValue(trim("SnapX"))
            snap_y = row.getValue(trim("SnapY"))
            setattr(nodes[id], LOCATION, (snap_x, snap_y))
          node_attribute_progress.step()
        if point_not_in_graph_count:
          AddWarning(WARNING_POINTS_NOT_IN_GRAPH(N,
              point_not_in_graph_count))
        AddMessage(STEP_3_FINISHED)
      except:
        AddWarning(GetMessages(2))
        AddMessage(STEP_3_FAILED)
        success = False

    # Step 4
    if success:
      AddMessage(STEP_4_STARTED)
      try:
        # Compute measures
        compute_centrality(nodes, selected_features, inputs[COMPUTE_REACH],
            inputs[COMPUTE_GRAVITY], inputs[COMPUTE_BETWEENNESS],
            inputs[COMPUTE_CLOSENESS], inputs[COMPUTE_STRAIGHTNESS],
            inputs[SEARCH_RADIUS], inputs[USE_NETWORK_RADIUS], inputs[BETA],
            inputs[NORMALIZE_RESULTS], accumulator_fields)
        AddMessage(STEP_4_FINISHED)
      except:
        AddWarning(GetMessages(2))
        AddMessage(STEP_4_FAILED)
        success = False

    # Step 5
    if success:
      AddMessage(STEP_5_STARTED)
      try:
        # Make output layer
        MakeFeatureLayer_management(in_features=output_feature_class,
            out_layer=output_layer_name)
        # Save output layer
        SaveToLayerFile_management(output_layer_name, output_layer,
            "ABSOLUTE")
        # Use a test node to figure out which metrics were computed
        test_node_id = selected_features.pop()
        # Make sure the test node is in the graph
        while test_node_id not in nodes:
          test_node_id = selected_features.pop()
        test_node = nodes[test_node_id]
        measures = set([measure for measure in dir(test_node) if (measure in
            FINAL_ATTRIBUTES or is_accumulator_field(measure))])
        # Add a field in the output layer for each computed metric
        for measure in measures:
          AddField_management(in_table=output_layer, field_name=trim(measure),
              field_type="DOUBLE", field_is_nullable="NON_NULLABLE")
        # Figure out the id field to use based on the type of input buildings
        if (buildings_description.shapeType == "Polygon" and
            inputs[ID_ATTRIBUTE] == ORIGINAL_FID):
          id_field = "FID"
        else:
          id_field = inputs[ID_ATTRIBUTE]
        # Fill the layer with the metric values
        write_progress = Progress_Bar(N, 1, STEP_5)
        layer_rows = UpdateCursor(output_layer)
        for row in layer_rows:
            id = row.getValue(id_field)
            for measure in measures:
              # If no value was computed for this node id, set value to 0
              value = 0
              if id in nodes and hasattr(nodes[id], measure):
                value = getattr(nodes[id], measure)
              row.setValue(trim(measure), value)
            layer_rows.updateRow(row)
            write_progress.step()
        # Save to toolbox output
        SetParameterAsText(OUTPUT_FEATURE_CLASS, output_feature_class)
        AddMessage(STEP_5_FINISHED)
      except:
        AddWarning(GetMessages(2))
        AddMessage(STEP_5_FAILED)
        success = False

    # Step 6
    if success:
      AddMessage(STEP_6_STARTED)
      # Apply symbology
      try:
        ApplySymbologyFromLayer_management(in_layer=output_layer,
            in_symbology_layer=symbology_layer)
      except:
        AddWarning(WARNING_APPLY_SYMBOLOGY_FAILED)
        AddWarning(GetMessages(2))
        AddMessage(STEP_6_FAILED)
      # Display
      try:
        current_map_document = mapping.MapDocument("CURRENT")
        data_frame = mapping.ListDataFrames(current_map_document,
            "Layers")[0]
        add_layer = mapping.Layer(output_layer)
        mapping.AddLayer(data_frame, add_layer, "AUTO_ARRANGE")
        AddMessage(STEP_6_FINISHED)
      except:
        AddWarning(WARNING_FAIL_TO_DISPLAY)
        AddWarning(GetMessages(2))
        AddMessage(STEP_6_FAILED)

    # Clean up
    clean_up()

    AddMessage(SUCCESS if success else FAILURE)

  except ExecuteAbort:
    clean_up()
Example #14
0
def mainProcessFeatureSimplification(inputFeatures, maxCount, outputFeatures):
    # Split the input features into intermediary features:
    # Add each intermediary feature class to a list and
    # pass one feature class of the intermediary features
    # to each subprocess.
    
    # When all of the subprocesses complete, use the
    # list of the intermediary feature classes to append
    # the data into the output features.
    
    countResult = GetCount_management(inputFeatures)
    intCount = int(countResult.getOutput(0))
    # debug print
    print("Counted " + str(intCount) + " features in the " + inputFeatures + " feature class.")
    
    if maxCount > 15000:
        maxCount = 15000
    elif maxCount < 2000:
        maxCount = 7000
    else:
        pass
    
    neededMirrors = intCount / maxCount + 1
    
    # debug print
    print("Will create " + str(neededMirrors) + " reflection gdbs.")
    
    infoForSubprocess = list()
    gdbToCreateList = list()
    
    for countItem in xrange(0, neededMirrors):
        gdbMirrorName = mirrorBaseName + '_' + '0' + str(countItem) + '.gdb'
        gdbMirrorFullPath = os.path.join(mainFolder, gdbMirrorName)
        gdbToCreateList.append(gdbMirrorFullPath)
        try:
            if Exists(gdbMirrorFullPath):
                try:
                    Delete_management(gdbMirrorFullPath)
                except:
                    pass
            else:
                pass
        except:
            pass
        
        CreateFileGDB_management(mainFolder, gdbMirrorName)
        
        # do a selection on the input features here
        # then copyfeatures to get the selected features
        # output to the target gdb.
        
        if Exists(simplifyTempLayer):
            try:
                Delete_management(simplifyTempLayer)
            except:
                pass
        else:
            pass
        
        MakeFeatureLayer_management(inputFeatures, simplifyTempLayer)
        
        currentSelectMin = int(countItem * maxCount) 
        currentSelectMax = int((countItem + 1) * maxCount)
        
        dynSelectClause = """"OBJECTID" >= """ + str(currentSelectMin) + """ AND "OBJECTID" < """ + str(currentSelectMax) + """"""
        
        SelectLayerByAttribute_management(simplifyTempLayer, "NEW_SELECTION", dynSelectClause)
        
        selectedSimplifyFeatures = os.path.join(gdbMirrorFullPath, simplifyInputName)
        
        CopyFeatures_management(simplifyTempLayer, selectedSimplifyFeatures)
        
        subprocessInfoItem = [mainFolder, gdbMirrorFullPath, simplifyAlgorithm, simplifyDistance]
        
        infoForSubprocess.append(subprocessInfoItem)
    
    # Predivide the list of data driven pages that each process needs to run
    # and pass it as a list of exportItems.
    
    coreCount = mp.cpu_count()
    
    # To support running this on the slow AR60, reduce the coreCount used to try to keep
    # this script from crashing there.
    if coreCount >= 3 and useMultithreading == True:
        coreCount = coreCount - 1
        
        print("Starting a multi-threaded job which will use (up to) " + str(coreCount) + " cores at once.")
        
        workPool = mp.Pool(processes=coreCount)
        # Note: This is a different usage of the word map than the one generally used in GIS.
        workPool.map(subProcessFeatureSimplification, infoForSubprocess)
        print("Multi-threaded job's done!")
        
        print("Waiting a few moments before closing down the worker processes...")
        time.sleep(20)
        workPool.close()
        time.sleep(20)
        workPool.join()
        
        print("Worker processes closed.")
        
    else:
        # Don't use multithreading here.
        print("Using the single threaded process for feature simplification.")
        print("This will be slower than the multi-threaded version,")
        print("but it should also be less likely to crash on slower machines")
        print("or those with low core counts.")
        for singleThreadedProcessInfoListItem in infoForSubprocess:
            singleThreadedProcessForSlowMachines(singleThreadedProcessInfoListItem)
        
        print("Waiting a few moments before continuing to the next part of the script...")
        time.sleep(20)
    
    # Delete the output target prior to recreating it and appending data into it.
    if Exists(outputFeatures):
        try:
            Delete_management(outputFeatures)
        except:
            pass
    else:
        pass
    
    # Need the gdb and fc name here from outputFeatures.
    outGDB = returnGDBOrSDEPath(outputFeatures)
    outGDBName = returnGDBOrSDEName(outGDB)
    outGDBFolder = returnGDBOrSDEFolder(outGDB)
    outFCName = returnFeatureClass(outputFeatures)
    
    if not Exists(outGDB):
        CreateFileGDB_management(outGDBFolder, outGDBName)
    
    # Use the inputFeatures as a template.
    CreateFeatureclass_management(outGDB, outFCName, "", inputFeatures)
    
    appendOutputFCList = list()
    
    for gdbToCreate in gdbToCreateList:
        appendOutputFC = os.path.join(gdbToCreate, 'simplificationOutput')
        appendOutputFCList.append(appendOutputFC)
    
    # Do appends here, then sleep again for a bit.
    # Shouldn't need a field mapping since they should all be the same.
    Append_management(appendOutputFCList, outputFeatures, "NO_TEST")
    
    print "Waiting a few moments to be sure that all of the locks have been removed prior to deleting the reflection gdbs..."
    time.sleep(20)
    
    # Then remove the mirror gdbs.
    for gdbToCreate in gdbToCreateList:
        try:
            if Exists(gdbToCreate):
                try:
                    Delete_management(gdbToCreate)
                except:
                    pass
            else:
                pass
        except:
            pass