Ejemplo n.º 1
0
def rand_string(resultsOutputQueue, xCount):
    """ Generates a random string of numbers, lower- and uppercase chars. """
    rand_str = ''.join(random.choice(
                    string.ascii_lowercase 
                    + string.ascii_uppercase 
                    + string.digits)
               for i in range(xCount))
    
    countedNumber = GetCount_management('Counties_No_Z')
    #output.put(rand_str + str(countedNumber))
    
    startTime = str(datetime.datetime.now())
    
    xCount = str(xCount)
    
    randomNumber = random.randint(1, 105)
    searchCursorWhereClause = "\"COUNTY_NUMBER\" = " + str(randomNumber) + " "
    
    newCursor = daSearchCursor('Counties_No_Z', ["COUNTY_NAME", "COUNTY_NUMBER", "SHAPE@"], searchCursorWhereClause)
    
    for rowItem in newCursor:
        rowItemString = "Cursor Row Item: " + str(rowItem[0]) + " & " + str(int(rowItem[1])) + "."
        
    endTime = str(datetime.datetime.now())
    
    resultsOutputQueue.put("Process number: " + xCount + "\n " + 
               "Started: " + startTime + " \n " + 
               "Ended: " + str(datetime.datetime.now()) + "\n " +
               rand_str + " " + str(countedNumber) + " " + str(rowItemString))
    
    if "newCursor" in locals():
        del newCursor
    else:
        pass
Ejemplo n.º 2
0
def rand_string(resultsOutputQueue, xCount):
    """ Generates a random string of numbers, lower- and uppercase chars. """
    rand_str = ''.join(
        random.choice(string.ascii_lowercase + string.ascii_uppercase +
                      string.digits) for i in range(xCount))

    countedNumber = GetCount_management('Counties_No_Z')
    #output.put(rand_str + str(countedNumber))

    startTime = str(datetime.datetime.now())

    xCount = str(xCount)

    randomNumber = random.randint(1, 105)
    searchCursorWhereClause = "\"COUNTY_NUMBER\" = " + str(randomNumber) + " "

    newCursor = daSearchCursor('Counties_No_Z',
                               ["COUNTY_NAME", "COUNTY_NUMBER", "SHAPE@"],
                               searchCursorWhereClause)

    for rowItem in newCursor:
        rowItemString = "Cursor Row Item: " + str(rowItem[0]) + " & " + str(
            int(rowItem[1])) + "."

    endTime = str(datetime.datetime.now())

    resultsOutputQueue.put("Process number: " + xCount + "\n " + "Started: " +
                           startTime + " \n " + "Ended: " +
                           str(datetime.datetime.now()) + "\n " + rand_str +
                           " " + str(countedNumber) + " " + str(rowItemString))

    if "newCursor" in locals():
        del newCursor
    else:
        pass
def writeStewardPointCounts():
    MakeFeatureLayer_management(originalPointsSource, originalPointsAsLayer)
    MakeFeatureLayer_management(simplifiedPointsSource, simplifiedPointsAsLayer)
    
    allStewardsDict = dict()
    
    #Programatically grab the stewards instead of manually listing them here
    newCursor = daSearchCursor(originalPointsAsLayer, ["OID@", "STEWARD"])
    
    for cursorItem in newCursor:
        allStewardsDict[cursorItem[1]] = 'True'
    
    if 'newCursor' in locals():
        try:
            del newCursor
        except:
            print("The cursor exists, but it could not be successfully removed.")
    else:
        print("The cursor has already been removed.")
    
    
    try:
        wHandle = open(outputFile,'w')
        columnNames = "StewardID , OriginalCount , SimplifiedCount\n"
        wHandle.write(columnNames)
        
        # For each steward in the list, get a count of all of the original centerline
        # points and the the simplified road centerlines points.
        # Next, write the data out to a text file in comma separated form.
        for stewardItem in allStewardsDict.keys():
            if stewardItem is not None:
                selectionQuery = """ "STEWARD" = '""" + stewardItem + """' """
                SelectLayerByAttribute_management(originalPointsAsLayer, selectionTypeToUse, selectionQuery)
                oCountResult = GetCount_management(originalPointsAsLayer)
                originalCount = int(oCountResult.getOutput(0))
                SelectLayerByAttribute_management(simplifiedPointsAsLayer, selectionTypeToUse, selectionQuery)
                sCountResult = GetCount_management(simplifiedPointsAsLayer)
                simplifiedCount = int(sCountResult.getOutput(0))
                strToWrite = "'" + stewardItem + "'" + ", " + str(originalCount) + ", " + str(simplifiedCount) + "\n"
                print("Writing " + strToWrite + " to the file: " + outputFile + ".")
                wHandle.write(strToWrite)
            else:
                print("The stewardItem is None, so it will be skipped.")
    
    except:
        errorInfo = sys.exc_info()[0]
        errorInfo1 = sys.exc_info()[1]
        print("An error occurred: " + str(errorInfo) + str(errorInfo1))
        try:
            wHandle.close()
        except:
            raise
        try:
            del errorInfo
            del errorInfo1
        except:
            pass
def getBorderFeatureList():
    print "Getting border feature list."
    
    borderFeatureCursor = daSearchCursor(countyBorderFeature, countyBorderFields)
    
    borderFeaturesToReturn = list()
    
    for borderFeature in borderFeatureCursor:
        borderFeaturesToReturn.append(borderFeature)
        
    # Just return the borderFeature... have other operations get the countyBorderFeatureCentroid
    # and countyBorderFeatureArea as needed.
    
    return borderFeaturesToReturn
Ejemplo n.º 5
0
def writeAggregateTableToKanDrive():
    try:
        #truncating CDRS segments in KanDrive Spatial
        print str(datetime.datetime.now()) + " truncating RCRS segments in KanDrive Spatial."
        TruncateTable_management(kanDriveSpatialConditions)
        
        featuresToTransfer = list()
        
        # searchCursorFields go to r"in_memory\RCRS". (Input table)(Indirect)
        descObject = Describe(r"in_memory\RCRS")
        searchCursorFields = [field.name for field in descObject.fields if 
                            field.name != descObject.OIDFieldName and field.name != "Shape" and
                            field.name != "ID1"]
        searchCursorFields.append('SHAPE@')
        
        RCRS_SearchCursor = daSearchCursor(aggregateTable, searchCursorFields)
		
        for RCRS_CursorItem in RCRS_SearchCursor:
			featureItem = list(RCRS_CursorItem)
			featuresToTransfer.append(featureItem)
        
        # Make the insertCursor use the same fields as the searchCursor.
        insertCursorFields = searchCursorFields
        
        RCRS_InsertCursor = daInsertCursor(kanDriveSpatialConditions, insertCursorFields)
            
        for RCRS_Feature in featuresToTransfer:
            insertOID = RCRS_InsertCursor.insertRow(RCRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)
		
    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement
        
        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging('KanDrive_Spatial_Conditions_Update', 'kandrive_spatial.DBO.Conditions',
            scriptFailure, startTime, endTime, errorItem.args[0], pythonLogTable)
            
        try:
            del errorItem
        except:
            pass
def getRoadLinesList():
    
    print "Getting the road lines list."
    # Need a new function here. -- Instead of calling this twice, have a main-style funtion
    # call it once and then pass it as an argument to both functions.
    roadCursor = daSearchCursor(countyRoadsFeature, roadCursorFields)  # @UndefinedVariable
    
    roadLinesToReturn = list()
    
    for roadPolyline in roadCursor:
        roadLinesToReturn.append(list(roadPolyline))
        
    if "roadCursor" in locals():
        del roadCursor
    else:
        pass
    
    return roadLinesToReturn
def manageLogLength():
    logTableDesc = Describe(pythonLogTable)
    logLengthCheckCursor = daSearchCursor(pythonLogTable, logTableDesc.OIDFieldName)

    shouldTruncate = False

    for logItem in logLengthCheckCursor:
        if int(logItem[0]) > 5000:
            shouldTruncate = True
        else:
            pass

    if shouldTruncate == True:
        print "Log table size is too big."
        print "Truncating log table."
        TruncateTable_management(pythonLogTable)
    else:
        pass
Ejemplo n.º 8
0
def manageLogLength():
    logTableDesc = Describe(pythonLogTable)
    logLengthCheckCursor = daSearchCursor(pythonLogTable, logTableDesc.OIDFieldName)

    shouldTruncate = False

    for logItem in logLengthCheckCursor:
        if int(logItem[0]) > 5000:
            shouldTruncate = True
        else:
            pass

    if shouldTruncate == True:
        print "Log table size is too big."
        print "Truncating log table."
        TruncateTable_management(pythonLogTable)
    else:
        pass
def getRoadLinesList():

    print "Getting the road lines list."
    # Need a new function here. -- Instead of calling this twice, have a main-style funtion
    # call it once and then pass it as an argument to both functions.
    roadCursor = daSearchCursor(countyRoadsFeature,
                                roadCursorFields)  # @UndefinedVariable

    roadLinesToReturn = list()

    for roadPolyline in roadCursor:
        roadLinesToReturn.append(list(roadPolyline))

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

    return roadLinesToReturn
def getBorderFeatureList(quarterOrHalf):

    if quarterOrHalf.lower() == "quarter":
        countyBorderFeature = countyBorderFeature_Q
    elif quarterOrHalf.lower() == "half":
        countyBorderFeature = countyBorderFeature_H
    else:
        print "quarterOrHalf variable not correctly defined."
        raise (Exception("quarterOrHalf error."))

    print "Getting border feature list."

    borderFeatureCursor = daSearchCursor(countyBorderFeature,
                                         countyBorderFields)

    borderFeaturesToReturn = list()

    for borderFeature in borderFeatureCursor:
        borderFeaturesToReturn.append(borderFeature)

    return borderFeaturesToReturn
def reportExtensionForCSIP(csipGDBWithOutput):
    # Create a blank line before the CSIP error counts.
    try:
        with open(errorReportCSV, 'a') as fHandle:
            fHandle.write('\n')
    except:
        print("There was an error writing to the file.")

    csipGDBWithOutputFrequencyTable = os.path.join(
        csipGDBWithOutput, "SelfIntersectingRoutes_CategoryCounts")
    if Exists(csipGDBWithOutputFrequencyTable):
        csipCursorFields = ["SelfIntersectionType", "FREQUENCY"]
        newCursor = daSearchCursor(csipGDBWithOutputFrequencyTable,
                                   csipCursorFields)
        errorDescriptionAndCountDict = dict()
        for cursorItem in newCursor:
            if cursorItem[0] is not None and cursorItem[1] is not None:
                errorDescriptionAndCountDict[cursorItem[0]] = cursorItem[1]
            else:
                print("Either the cursorItem[0] or cursorItem[1] were none.")
                print(
                    "Will not add this cursorItem to the csip output dictionary."
                )

        # To get the listed error descriptions with associated counts, in order.
        for errorDescToRecordFirst in csip_ordered_report_rows:
            errorDescription = errorDescToRecordFirst
            errorCount = errorDescriptionAndCountDict.get(
                errorDescToRecordFirst, None)
            if errorCount is not None:
                print("There were " + str(errorCount) +
                      " errors features with the description of: \t" +
                      str(errorDescription) + ".")
                try:
                    with open(errorReportCSV, 'a') as fHandle:
                        fHandle.write(errorDescription + ', ' +
                                      str(errorCount) + '\n')
                except:
                    print("There was an error writing to the file.")
            else:
                print("There were 0 errors with the description of: \t" +
                      str(errorDescription) + ".")
                try:
                    with open(errorReportCSV, 'a') as fHandle:
                        fHandle.write(errorDescription + ', ' + '0' + '\n')
                except:
                    print("There was an error writing to the file.")

        complexSelfIntersectionsCount = 0
        # To get the unlisted error descriptions with associated counts, in no particular order.
        for errorDescription in errorDescriptionAndCountDict.keys():
            if errorDescription not in csip_ordered_report_rows:
                if errorDescription.find(
                        'Complex') >= 0:  # Returns -1 if not found.
                    errorCount = errorDescriptionAndCountDict[errorDescription]
                    complexSelfIntersectionsCount += int(errorCount)
                elif errorDescription == 'Not self-intersecting':
                    pass
                else:
                    # This is an issue. Print a warning.
                    print("Warning: The error description of '" +
                          str(errorDescription) + "'")
                    print(
                        "is neither in the csip_ordered_report_rows list, nor is it a Complex Self-Intersection."
                    )
            else:
                pass  # This should have already been recorded.

        try:
            with open(errorReportCSV, 'a') as fHandle:
                fHandle.write('Complex Self-Intersection' + ', ' +
                              str(complexSelfIntersectionsCount) + '\n')
        except:
            print("There was an error writing to the file.")

    else:
        print("Could not find the Output Frequency Table in the csip GDB.")
def featureReplacement(sourceFL, targetFL, featuresToSelect):
    # 1c.) Get the common fields so that you can search and insert correctly.
    targetFeatureDesc = Describe(targetFL)
    targetFeatureFields = targetFeatureDesc.fields
    targetFeatureOIDField = targetFeatureDesc.OIDFieldName
    targetFeatureShapeField = targetFeatureDesc.shapeFieldName
    targetFeatureFieldNames = [x.name for x in targetFeatureFields]
    
    sourceFeatureDesc = Describe(sourceFL)
    sourceFeatureFields = sourceFeatureDesc.fields
    sourceFeatureOIDField = sourceFeatureDesc.OIDFieldName
    sourceFeatureShapeField = sourceFeatureDesc.shapeFieldName
    sourceFeatureFieldNames = [x.name for x in sourceFeatureFields]
    
    excludeFieldNames = [targetFeatureOIDField, targetFeatureShapeField, sourceFeatureOIDField, sourceFeatureShapeField]
    
    searchCursorFields = [x for x in targetFeatureFieldNames if x in sourceFeatureFieldNames and x not in excludeFieldNames]
    searchCursorFields.append('SHAPE@')
    
    # Remove and then re-add the uniqueKeyField so that it is the last column and can be easily referenced.
    searchCursorFields.remove(str(uniqueKeyFieldToUse))
    searchCursorFields.append(str(uniqueKeyFieldToUse))
    insertCursorFields = searchCursorFields
    
    # Select the features in the source layer
    SelectLayerByAttribute_management(sourceFL, "NEW_SELECTION", featuresToSelect)
    # Repeat the selection in the target layer
    SelectLayerByAttribute_management(targetFL, "NEW_SELECTION", featuresToSelect)
    # Then select the common segments spatially, with some room for possible movement.
    SelectLayerByLocation_management(targetFL, 'WITHIN_A_DISTANCE', sourceFL, 50, 'SUBSET_SELECTION')
    
    # 5.) Count selected features in the target and delete them if there is at least 1.
    countResult0 = GetCount_management(targetFL)
    intCount0 = int(countResult0.getOutput(0))
    if intCount0 >= 1:
        # 12.) Delete the selected features in the input layer, if any.
        try:
            DeleteFeatures_management(targetFL)
        except:
            print("Could not delete features for the selection " + str(featuresToSelect) + ".")
    else:
        pass
    
    # 10.) Count to make sure that at least one feature is selected.
    countResult1 = GetCount_management(sourceFL)
    intCount1 = int(countResult1.getOutput(0))
    if intCount1 >= 1:
        # If so, cursor the features out
        featureList = list()
        
        newCursor = daSearchCursor(sourceFL, searchCursorFields)
        
        for cursorItem in newCursor:
            featureList.append(list(cursorItem))
        
        try:
            del newCursor
        except:
            pass
        
        # 11.) Insert the selected source features into the copy of the centerlines.
        newCursor = daInsertCursor(targetFL, insertCursorFields)
        
        for featureItem in featureList:
            newCursor.insertRow(featureItem)
        
        try:
            del newCursor
        except:
            pass
        try:
            del featureList
        except:
            pass
def importCommentsToChangedSource(sourceWithComments, targetToHaveCommentsAdded):
    # Since I forgot to ask that the ReviewUser and ReviewInfo fields be kept, need to get the
    # data back. Thankfully, it appears to still be in the same objectID order, so we can
    # use that and the GCIDs to try to transfer it over, then make additional quality checks
    # to be sure that the transfer was successful and did not introduce any errors.
    # 0.) Add the ReviewUser and ReviewInfo fields to the copy if they do not already exist.
    #       That way, the information from the edits can flow through to future edit sessions
    #       and error checks.
    tfcDesc = Describe(targetToHaveCommentsAdded)
    tfcFields = tfcDesc.fields
    tfcFieldNames = [x.name for x in tfcFields]
    
    try:
        del tfcDesc
    except:
        pass
    
    # Check for ReviewUser field in the targetFeaturesCopy, then add it if missing.
    if 'ReviewUser' not in tfcFieldNames:
        #ReviewUser (String, 50)
        AddField_management(targetToHaveCommentsAdded, 'ReviewUser', "TEXT", "", "", 50, 'ReviewUser', nullable)
    else:
        pass
    
    # Check for ReviewInfo field in the targetFeaturesCopy, then add it if missing.
    if 'ReviewInfo' not in tfcFieldNames:
        #ReviewInfo (String, 250)
        AddField_management(targetToHaveCommentsAdded, 'ReviewInfo', "TEXT", "", "", 250, 'ReviewInfo', nullable)
    else:
        pass
    
    tfcUpdatedDesc = Describe(targetToHaveCommentsAdded)
    tfcUpdatedFields = tfcUpdatedDesc.fields
    tfcUpdatedOIDFieldName = tfcUpdatedDesc.OIDFieldName
    tfcUpdatedFieldNames = [x.name for x in tfcUpdatedFields]
    
    try:
        del tfcUpdatedDesc
    except:
        pass
    try:
        tfcUpdatedFieldNames.remove(tfcUpdatedOIDFieldName)
    except:
        pass
    try:
        tfcUpdatedFieldNames.remove(GCIDFieldName)
    except:
        pass
    
    tfcUpdatedFieldNames.append(tfcUpdatedOIDFieldName)
    tfcUpdatedFieldNames.append(GCIDFieldName)
    
    swcDesc = Describe(sourceWithComments)
    swcFields = swcDesc.fields
    swcOIDFieldName = swcDesc.OIDFieldName
    swcFieldNames = [x.name for x in swcFields]
    
    try:
        del swcDesc
    except:
        pass
    try:
        swcFieldNames.remove(swcOIDFieldName)
    except:
        pass
    try:
        swcFieldNames.remove(GCIDFieldName)
    except:
        pass
    
    swcFieldNames.append(swcOIDFieldName) # Add the OIDFieldName so that it is the 2nd to last
    swcFieldNames.append(GCIDFieldName) # Add 'GCID' so that it is the last
    
    sharedFieldNames = [x for x in tfcUpdatedFieldNames if x in swcFieldNames]
    
    # 1.) Use a searchCursor to pull the sourceWithComments features, including the OID and their GCID.
    withCommentsList = list()
    newCursor = daSearchCursor(sourceWithComments, sharedFieldNames)
    
    for cursorRow in newCursor:
        withCommentsList.append(cursorRow)
    
    try:
        del newCursor
    except:
        pass
    
    print("The sharedFieldNames are: " + str(sharedFieldNames) + ".")
    # 2.) Use an updateCursor to match the pulled rows and update the target rows with the ReviewUser and ReviewInfo.
    newCursor = daUpdateCursor(targetToHaveCommentsAdded, sharedFieldNames)
    
    for cursorRow in newCursor:
        for commentedRowItem in withCommentsList:
            if cursorRow[-1] == commentedRowItem[-1] and cursorRow[-2] == commentedRowItem[-2]:
                print ('Updating a row with GCID: ' + str(cursorRow[-1]) + ' and OID: ' + str(cursorRow[-2]) + '.')
                newCursor.updateRow(commentedRowItem)
    
    try:
        del newCursor
    except:
        pass
Ejemplo n.º 14
0
def createUniqueIdentifier():
    '''filters through records and calculates an incremental Unique Identifier for routes that are not border routes, to handle Y's, eyebrows, and splits that would cause complex routes'''
    workspaceLocation = gdb
    #MakeFeatureLayer_management(lyr,"RCL_Particles",where_clause="COUNTY_L = COUNTY_R AND STATE_L = STATE_R AND ( L_F_ADD =0 OR L_T_ADD =0 OR R_F_ADD =0 OR R_T_ADD =0)")
    featureClassName = lyr
    #from arcpy.da import SearchCursor as daSearchCursor, UpdateCursor as daUpdateCursor, Editor as daEditor
    alphabetListForConversion = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    newCursor = daSearchCursor(featureClassName, uniqueIdInFields)
    searchList = list()
    for searchRow in newCursor:
        searchList.append(list(searchRow)) # Transforms the row tuple into a list so it can be edited.

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

    matchCount = 0
    matchList = list()

    for testRow in searchList:
        if (testRow[1] == testRow[2] and testRow[3] == testRow[4] and (str(testRow[5]) == "0" or str(testRow[6]) == "0" or str(testRow[7]) == "0" or str(testRow[8]) == "0")):
            matchCount += 1
            matchList.append(testRow)

    matchedRowDictionary = dict()

    for matchedRow in matchList:
        matchedRowContainer = list()
        # If the key already exists, assign the previous list of lists
        # to the list container, then append the new list
        # before updating the new value to that key in the dictionary.
        if matchedRow[10] in matchedRowDictionary:
            matchedRowContainer = matchedRowDictionary[matchedRow[10]]
            matchedRowContainer.append(matchedRow)
            matchedRowDictionary[matchedRow[10]] = matchedRowContainer
        # Otherwise, the key needs to be created
        # with the value, the list container, having only
        # one list contained within it for now.
        else:
            matchedRowContainer.append(matchedRow)
            matchedRowDictionary[matchedRow[10]] = matchedRowContainer

    for LRSKey in matchedRowDictionary:
        outRowContainer = matchedRowDictionary[LRSKey]
        # Sort based on length
        outRowContainer = sorted(outRowContainer, key = lambda sortingRow: sortingRow[11])
        countVariable = 0 # Start at 0 for unique values
        LRSVariable = ""
        for outRowIndex, outRow in enumerate(outRowContainer):
            # Is this the first list/row in the key's list container?
            # If so, then set the Resolution_Order to 0
            if outRowIndex == 0:
                outRow[9] = 0
            else:
                countVariable += 1
                if countVariable in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
                    outRow[9] = countVariable
                elif countVariable >= 10 and countVariable <= 34:
                    outRow[9] = alphabetListForConversion[countVariable - 10] # Converts countVariable to an alpha character, without the letter "O".
                else:
                    print "The count Variable is above 34. Ran out of numbers and letters to use as unique values."

            LRSVariable = outRow[10]
            LRSVariableShortened = str(LRSVariable[:-1]) # Returns the LRSVariable without the last character.
            LRSVariable = LRSVariableShortened + str(outRow[9])
            outRow[10] = LRSVariable

            outRowString = ""

            for outRowElement in outRow:
                outRowString = outRowString + str(outRowElement) + " "

            print outRowString

            outRowContainer[outRowIndex] = outRow

        matchedRowDictionary[LRSKey] = outRowContainer

    newEditingSession = daEditor(workspaceLocation)
    newEditingSession.startEditing()
    newEditingSession.startOperation()

    newCursor = daUpdateCursor(featureClassName, uniqueIdOutFields)  # @UndefinedVariable
    for existingRow in newCursor:
        formattedOutRow = list()
        if existingRow[2] in matchedRowDictionary.keys():
            outRowContainer = matchedRowDictionary[existingRow[2]]
            for outRow in outRowContainer:
                if existingRow[0] == outRow[0]: # Test for matching OBJECTID fields.
                    formattedOutRow.append(outRow[0])
                    formattedOutRow.append(outRow[9])
                    formattedOutRow.append(outRow[10])
                    newCursor.updateRow(formattedOutRow)
                else:
                    pass

        else:
            pass

    newEditingSession.stopOperation()
    newEditingSession.stopEditing(True)

    if "newCursor" in locals():
        del newCursor
    else:
        pass
Ejemplo n.º 15
0
def TnA():
    try:
        env.workspace = stagews
        #copying oracle tables to memory
        print str(datetime.datetime.now()) + ' copying oracle tables to memory'
        FeatureClassToFeatureClass_conversion(sdeCDRS,"in_memory","Construction","#","ALERT_STATUS <>  3")
        MakeQueryTable_management(sdeCDRSWZ,"wz1","USE_KEY_FIELDS","KANROAD.CDRS_WZ_DETAIL.CDRS_WZ_DETAIL_ID",
                                """KANROAD.CDRS_WZ_DETAIL.CDRS_WZ_DETAIL_ID #;KANROAD.CDRS_WZ_DETAIL.CDRS_DETOUR_TYPE_ID #;
                                KANROAD.CDRS_WZ_DETAIL.WORK_ZONE_DESC #;KANROAD.CDRS_WZ_DETAIL.WORK_ZONE_SPEED_RESTRIC #;
                                KANROAD.CDRS_WZ_DETAIL.DETOUR_TYPE_TXT #;KANROAD.CDRS_WZ_DETAIL.DETOUR_SPEED_RESTRIC #;
                                KANROAD.CDRS_WZ_DETAIL.DETOUR_DESC #""", "#")
        TableToTable_conversion("wz1", 'in_memory', 'wz')
        #Joining the Oracle CDRS WZ table
        print str(datetime.datetime.now()) + " Joining the Oracle CDRS WZ table"
        MakeFeatureLayer_management("Construction", "ConstJoin")
        AddJoin_management("ConstJoin","CDRS_WZ_DETAIL_ID","wz","KANROAD_CDRS_WZ_DETAIL_CDRS_WZ_DETAIL_ID","KEEP_ALL")
        FeatureClassToFeatureClass_conversion("ConstJoin","in_memory","CDRS","#",'ConstJoin.ALERT_STATUS <  3', "#")
        #reformatting the Route name for US routes
        print str(datetime.datetime.now()) + " reformatting the Route name for US routes"
        AddField_management("CDRS", "RouteName", "TEXT", "#", "10")
        routenamed = '!Construction_BEG_LRS_ROUTE![0:1] +str(!Construction_BEG_LRS_ROUTE![3:6]).lstrip("0")'  # calculation expression
        #Calculate the Route names for User Display
        print routenamed
        CalculateField_management("CDRS", "RouteName", routenamed, "PYTHON_9.3","#") 
        AddField_management("CDRS", "STATUS", "TEXT", "#", "10")
        AddField_management("CDRS", "Alert_Status_I", "LONG", "#", "#")
        CalculateField_management("CDRS", "Alert_Status_I", '!Construction_ALERT_STATUS!' , "PYTHON_9.3", "#") 
        #Assigning projection for KanRoad CDRS Alert Route Layer
        print str(datetime.datetime.now()) + " Assigning projection for KanRoad CDRS Alert Route Layer"
        DefineProjection_management("CDRS", lambertCC)
        #reformatting the Route name for US routes
        print str(datetime.datetime.now()) + " reformatting the Route name for US routes"
        MakeFeatureLayer_management("CDRS", "ACTIVERoutes", '"Construction_ALERT_STATUS" =  2' )
        CalculateField_management("ACTIVERoutes","STATUS",'"Active"',"PYTHON_9.3","#") 
        
        MakeFeatureLayer_management("CDRS", "ClosedRoutes", '"Construction_ALERT_STATUS" =  2 AND "Construction_FEA_CLOSED" =  1')
        CalculateField_management("ClosedRoutes","STATUS",'"Closed"',"PYTHON_9.3","#") 
        
        MakeFeatureLayer_management("CDRS", "PlannedRoutes", '"Construction_ALERT_STATUS" =  1' )
        CalculateField_management("PlannedRoutes","STATUS",'"Planned"',"PYTHON_9.3","#")
        
        #copying joined oracle tables to memory for loading in Wichway Schema
        print str(datetime.datetime.now()) + " copying joined oracle tables to memory for loading in Wichway Schema"
        FeatureClassToFeatureClass_conversion(sdeKandriveConstruction, "in_memory", "CDRS_Segments", "#", "#")
        
        #delete rows in the destination feature class
        DeleteRows_management("CDRS_Segments")
        
        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to the searchCursorFields and the
        # insertCursorFields lists and make sure that it is in the same position in the list order for both of
        # them.
        # Besides 'LoadDate', the order does not matter, so long as each field name in the
        # searchCursorFields has a counterpart in the insertCursorFields and vice versa.
        # 'LoadDate' should always be last for the insertCursorFields as it is appended to each row after all
        # of the other items from the searchCursorFields.
        ###############################################################################################################
        
        featuresToTransfer = list()
        
        # searchCursorFields go to "in_memory\CDRS". (Input table)
        searchCursorFields = ['SHAPE@', 'RouteName', 'Construction_BEG_STATE_LOGMILE', 'Construction_END_STATE_LOGMILE', 'Construction_BEG_COUNTY_NAME', 
                            'Construction_ALERT_DATE', 'Construction_COMP_DATE', 'Construction_ALERT_TYPE_TXT', 'Construction_ALERT_DESC_TXT',
                            'Construction_VERT_RESTRICTION', 'Construction_WIDTH_RESTRICTION', 'Construction_TIME_DELAY_TXT',
                            'Construction_PUBLIC_COMMENT', 'wz_KANROAD_CDRS_WZ_DETAIL_DETOUR_TYPE_TXT',
                            'wz_KANROAD_CDRS_WZ_DETAIL_DETOUR_DESC', 'Construction_CONTACT_NAME', 'Construction_CONTACT_PHONE', 
                            'Construction_CONTACT_EMAIL', 'Construction_ALERT_HYPERLINK',  'Alert_Status_I',
                            'Construction_FEA_CLOSED', 'STATUS', 'Construction_ALERT_DIREC_TXT', 'Construction_BEG_LONGITUDE',
                            'Construction_BEG_LATITUDE']
        
        # insertCursorFields go to sdeKandriveConstruction. (Output table)
        insertCursorFields = ['SHAPE@', 'RouteName', 'BeginMP', 'EndMP', 'County', 'StartDate', 'CompDate', 'AlertType', 'AlertDescription',
                            'HeightLimit', 'WidthLimit', 'TimeDelay', 'Comments', 'DetourType', 'DetourDescription',
                            'ContactName', 'ContactPhone', 'ContactEmail', 'WebLink',  'AlertStatus', 'FeaClosed', 'Status',
                            'AlertDirectTxt', 'X', 'Y', 'LoadDate']
        
        cdrsSearchCursor = daSearchCursor(r"in_memory\CDRS", searchCursorFields, """ "Alert_Status_I" <> 3""")
        
        for cdrsCursorItem in cdrsSearchCursor:
            featureItem = list(cdrsCursorItem)
            featureItem.append(starttime)
            featuresToTransfer.append(featureItem)
        
        ##Debug
        for feature in featuresToTransfer:
            print feature
        ##
        
        RemoveJoin_management("ConstJoin", "wz")
        
        #truncating CDRS segments in WICHWAY SPATIAL
        print str(datetime.datetime.now()) + " truncating CDRS segments in WICHWAY SPATIAL"
        
        TruncateTable_management(sdeKandriveConstruction)
        
        cdrsInsertCursor = daInsertCursor(sdeKandriveConstruction, insertCursorFields)
        
        for cdrsFeature in featuresToTransfer:
            insertOID = cdrsInsertCursor.insertRow(cdrsFeature)
            print "Inserted a row with the OID of: " + str(insertOID)
    
    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        print errorItem.args[0]
        try:
            del errorItem
        except:
            pass
        raise
    finally:
        try:
            del cdrsSearchCursor
        except:
            pass
        try:
            del cdrsInsertCursor
        except:
            pass
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
def transferFeatures():
    env.workspace = in_memory
    featuresToTransfer = list()
    try:
        # Create an in_memory feature class which to hold the features from
        # the Oracle table.
        FeatureClassToFeatureClass_conversion(kanRoadRCRSRoads, "in_memory", "RCRS")

        # Then, define a projection on it, since the original Oracle table
        # is lacking the proper information.
        DefineProjection_management("in_memory\RCRS", lambertCC)

        # truncating CDRS segments in KanDrive Spatial
        print str(datetime.datetime.now()) + " truncating RCRS segments in KanDrive Spatial."
        TruncateTable_management(kanDriveSpatialConditions)

        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to both of the
        # tables and give it the same name in both.
        ###############################################################################################################

        # searchCursorFields go to r"in_memory\RCRS". (Input table)(Indirect)
        descObject = Describe(r"in_memory\RCRS")
        searchCursorFields = [
            field.name
            for field in descObject.fields
            if field.name != descObject.OIDFieldName and field.name != "Shape" and field.name != "ID1"
        ]
        searchCursorFields.append("SHAPE@")

        # Make the insertCursor use the same fields as the searchCursor.
        insertCursorFields = searchCursorFields

        print "OIDFieldname = " + descObject.OIDFieldName

        print "fieldNames to be used in the searchCursor (and insertCursor):"
        for fieldName in searchCursorFields:
            print fieldName

        RCRS_SearchCursor = daSearchCursor(r"in_memory\RCRS", searchCursorFields)

        for RCRS_CursorItem in RCRS_SearchCursor:
            featureItem = list(RCRS_CursorItem)
            featuresToTransfer.append(featureItem)

        RCRS_InsertCursor = daInsertCursor(kanDriveSpatialConditions, insertCursorFields)

        for RCRS_Feature in featuresToTransfer:
            insertOID = RCRS_InsertCursor.insertRow(RCRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)

    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement

        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging(
            "KanDrive_Spatial_Conditions_Update",
            "kandrive_spatial.DBO.Conditions",
            scriptFailure,
            startTime,
            endTime,
            errorStatement,
            pythonLogTable,
        )

        try:
            del errorItem
        except:
            pass

            # Reraise the error to stop execution and prevent a success message
            # from being inserted into the table.
        raise

    finally:
        try:
            del RCRS_SearchCursor
        except:
            pass
        try:
            del RCRS_InsertCursor
        except:
            pass
Ejemplo n.º 18
0
def transferBasedOnLocalRouteKeys():
    # Build a list of the unique route keys that match the given criteria:
    # Then, use that list to select the features in the source with those
    # keys.
    # Next, spatially select features in the target layer with the
    # selected features from the source layer.
    # If there are more than 0 features selected, delete the selected
    # target features.
    # Then, cursor in the selected source features.

    subsetSelectionQuery = """ KDOT_LRS_KEY LIKE '%L%' AND NOT KDOT_LRS_KEY LIKE '%W%' """

    fcAsFeatureLayerForTransferring = 'FCAsFeatureLayer_Transferring'

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

    MakeFeatureLayer_management(fcWithroutesToTransferFrom,
                                fcAsFeatureLayerForTransferring)
    MakeFeatureLayer_management(targetFC1, targetFC1asFeatureLayer)

    lrsKeyFieldList = [str(lrsKeyToUse)]
    newCursor = daSearchCursor(fcWithroutesToTransferFrom, lrsKeyFieldList,
                               subsetSelectionQuery)
    uniqueLRSKeysDict = dict()
    for cursorRow in newCursor:
        uniqueLRSKeysDict[str(cursorRow[0])] = 1

    try:
        del newCursor
    except:
        pass

    uniqueLRSKeysList = uniqueLRSKeysDict.keys()
    try:
        uniqueLRSKeysList.remove('None')
    except:
        print(
            "Could not remove 'None' from the list of uniqueLRSKeys since it was not a part of the list."
        )

    print("LRSKey list creation successful.")
    print('Found ' + str(len(uniqueLRSKeysList)) +
          ' unique LRS Keys in the centerline data for this query:')
    print(str(subsetSelectionQuery))

    #Use multiSelection

    multiSelectionQueryBase = str(
        str(subsetSelectionQuery) + ''' AND ''' + ''' "''' + str(lrsKeyToUse) +
        '''" IS NOT NULL AND "''' + str(lrsKeyToUse) + '''" IN (''')
    multiSelectionQuery = multiSelectionQueryBase
    multiCounter = 0
    ##multiDissolveFields = [str(lrsKeyToUse), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX', 'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
    ##    'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L', 'KDOT_COUNTY_R']
    ##multiDissolveFields = str(lrsKeyToUse) + ';LRS_COUNTY_PRE;LRS_ROUTE_PREFIX;LRS_ROUTE_NUM;LRS_ROUTE_SUFFIX;LRS_UNIQUE_IDENT;LRS_UNIQUE_IDENT1'
    ##multiStatsFields = str(n1FromMeas) + " MIN;" + str(n1ToMeas) + " MAX"
    ##multiStatsFields = ""
    ##singlePart = "SINGLE_PART"
    ##unsplitLines = "UNSPLIT_LINES"

    # 3.) Loop through the list of unique LRS Keys
    for uniqueKeyItem in uniqueLRSKeysList:
        # Make a selection list that includes 50 keys, then select the keys and dissolve to make a new
        # feature class.
        # After the selection is dissolved, use a spatial select on the original feature class and
        # an attribute selection on the original feature class to see which original features should
        # be deleted.
        # Then, delete the selected features (if at least 1 selected).

        # Basically, doing it piece by piece is a problem since I'm not including LRS KEY
        # selections to prevent the spatial selection from deleting pieces that overlap, but
        # that should have different LRS Keys. Need to do all of the features
        # at once to make sure that I'm not deleting pieces that should actually be there.
        # Seems like it shouldn't be a problem, but the numbers say it is.
        # 4.) For groups of 200000 LRS Keys, select all the features with those LRS Keys.
        if multiCounter <= 199999:
            multiSelectionQuery += """'""" + str(
                uniqueKeyItem) + """'""" + """, """
            multiCounter += 1
        else:
            # Add the current item, then
            multiSelectionQuery += """'""" + str(
                uniqueKeyItem) + """'""" + """, """
            # Remove the trailing ", " and add a closing parenthesis.
            multiSelectionQuery = multiSelectionQuery[:-2] + """) """
            SelectLayerByAttribute_management(fcAsFeatureLayerForTransferring,
                                              "NEW_SELECTION",
                                              multiSelectionQuery)
            # Have to do from step 5 on here also.

            ### -shouldbeafunctionblock#1- ###
            # 5.) Count selected features.
            countResult0 = GetCount_management(fcAsFeatureLayerForTransferring)
            intCount0 = int(countResult0.getOutput(0))
            if intCount0 >= 1:
                print(
                    "Spatially selecting with the fcAsFeatureLayerForTransferring features, of which there are "
                    + str(intCount0) + " selected.")
                ##print("Selected by this query:")
                ##print(str(multiSelectionQuery))
                # 9.) Else, spatially select features in the original feature class with 'SHARE_A_LINE_SEGMENT_WITH'.
                SelectLayerByLocation_management(
                    targetFC1asFeatureLayer, "SHARE_A_LINE_SEGMENT_WITH",
                    fcAsFeatureLayerForTransferring, 0, "NEW_SELECTION")
                # Added to prevent the Selection from taking over '%W%' routes at this time.
                SelectLayerByAttribute_management(targetFC1asFeatureLayer,
                                                  "SUBSET_SELECTION",
                                                  subsetSelectionQuery)

                # 10.) Count to make sure that at least one feature is selected.
                countResult2 = GetCount_management(targetFC1asFeatureLayer)
                intCount2 = int(countResult2.getOutput(0))
                print(
                    'There were ' + str(intCount2) +
                    ' features selected for replacement in the targetFC1asFeatureLayer layer.'
                )
                if intCount2 >= 1:
                    # 11.) If so, cursor the features out of the dissolve layer.
                    featureList = list()
                    searchCursorFields = [
                        str(lrsKeyToUse),
                        str(startMeasure),
                        str(endMeasure), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
                        'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX',
                        'LRS_UNIQUE_IDENT', 'LRS_UNIQUE_IDENT1',
                        'KDOT_COUNTY_L', 'KDOT_COUNTY_R', 'LABEL', 'SHAPE@'
                    ]
                    newCursor = daSearchCursor(fcAsFeatureLayerForTransferring,
                                               searchCursorFields)

                    for cursorItem in newCursor:
                        featureList.append(list(cursorItem))

                    try:
                        del newCursor
                    except:
                        pass

                    # 12.) Delete the selected features in the input layer.
                    try:
                        DeleteFeatures_management(targetFC1asFeatureLayer)
                    except:
                        print("Could not delete features for the selection " +
                              str(multiSelectionQuery) + ".")
                    # 13.) Insert the features from the dissolve layer into the copy of the centerlines.
                    insertCursorFields = [
                        str(lrsKeyToUse),
                        str(startMeasure),
                        str(endMeasure), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
                        'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX',
                        'LRS_UNIQUE_IDENT', 'LRS_UNIQUE_IDENT1',
                        'KDOT_COUNTY_L', 'KDOT_COUNTY_R', 'LABEL', 'SHAPE@'
                    ]
                    newCursor = daInsertCursor(targetFC1asFeatureLayer,
                                               insertCursorFields)

                    for featureItem in featureList:
                        newCursor.insertRow(featureItem)

                    try:
                        del newCursor
                    except:
                        pass
                    try:
                        del featureList
                    except:
                        pass

                else:
                    pass
            ### -shouldbeafunctionblock#1- ###
            multiSelectionQuery = ''' "''' + str(
                lrsKeyToUse) + '''" IS NOT NULL AND "''' + str(
                    lrsKeyToUse) + '''" IN ('''
            multiCounter = 0

    # After the for loop, if there is still anything remaining which was unselected in the
    # the previous multiSelectionQuery steps.
    # Remove the trailing ", " and add a closing parenthesis.
    if multiSelectionQuery != multiSelectionQueryBase:
        multiSelectionQuery = multiSelectionQuery[:-2] + """) """
    else:
        # The selection query would not select anything.
        return
    SelectLayerByAttribute_management(fcAsFeatureLayerForTransferring,
                                      "NEW_SELECTION", multiSelectionQuery)

    # Then redo from step 5 on at the end of the loop IF there is anything left to select
    # which was not selected... so if selectionCounter != 0.

    ### -shouldbeafunctionblock#2- ###
    # 5.) Count selected features.
    countResult0 = GetCount_management(fcAsFeatureLayerForTransferring)
    intCount0 = int(countResult0.getOutput(0))
    if intCount0 >= 1:
        print(
            "Spatially selecting with the fcAsFeatureLayerForTransferring features, of which there are "
            + str(intCount0) + " selected.")
        ##print("Selected by this query:")
        ##print(str(multiSelectionQuery))
        # 9.) Else, spatially select features in the original feature class with 'SHARE_A_LINE_SEGMENT_WITH'.
        SelectLayerByLocation_management(targetFC1asFeatureLayer,
                                         "SHARE_A_LINE_SEGMENT_WITH",
                                         fcAsFeatureLayerForTransferring, 0,
                                         "NEW_SELECTION")
        # Added to prevent the Selection from taking over '%W%' routes at this time.
        SelectLayerByAttribute_management(targetFC1asFeatureLayer,
                                          "SUBSET_SELECTION",
                                          subsetSelectionQuery)

        # 10.) Count to make sure that at least one feature is selected.
        countResult2 = GetCount_management(targetFC1asFeatureLayer)
        intCount2 = int(countResult2.getOutput(0))
        print(
            'There were ' + str(intCount2) +
            ' features selected for replacement in the targetFC1asFeatureLayer layer.'
        )
        if intCount2 >= 1:
            # 11.) If so, cursor the features out of the dissolve layer.
            featureList = list()
            searchCursorFields = [
                str(lrsKeyToUse),
                str(startMeasure),
                str(endMeasure), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
                'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
                'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L', 'KDOT_COUNTY_R', 'LABEL',
                'SHAPE@'
            ]
            newCursor = daSearchCursor(fcAsFeatureLayerForTransferring,
                                       searchCursorFields)

            for cursorItem in newCursor:
                featureList.append(list(cursorItem))

            try:
                del newCursor
            except:
                pass

            # 12.) Delete the selected features in the input layer.
            try:
                DeleteFeatures_management(targetFC1asFeatureLayer)
            except:
                print("Could not delete features for the selection " +
                      str(multiSelectionQuery) + ".")
            # 13.) Insert the features from the dissolve layer into the copy of the centerlines.
            insertCursorFields = [
                str(lrsKeyToUse),
                str(startMeasure),
                str(endMeasure), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
                'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
                'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L', 'KDOT_COUNTY_R', 'LABEL',
                'SHAPE@'
            ]
            newCursor = daInsertCursor(targetFC1asFeatureLayer,
                                       insertCursorFields)

            for featureItem in featureList:
                newCursor.insertRow(featureItem)

            try:
                del newCursor
            except:
                pass
            try:
                del featureList
            except:
                pass

        else:
            pass
def dissolveBasedOnLocalRouteKeys(routesToDissolve, subsetSelectionQuery):
    # Moved out the selection building code to the other function where
    # it makes more sense.
    # Use similar code here to what is found in the main dissolve loop.
    # Just need to do multiselection on all of the possible routes that
    # match the subsetSelectionQuery and for each multiselection, create
    # a dissolve feature set, then use the same reintroduction tests
    # that are used in the main dissolve to reintroduce the dissolved
    # lines without removing any that weren't dissolved or adding
    # any new overlaps.

    fcAsFeatureLayerForDissolves = 'FCAsFeatureLayer_Dissolves'

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

    MakeFeatureLayer_management(routesToDissolve, fcAsFeatureLayerForDissolves)

    lrsKeyFieldList = [str(lrsKeyToUse)]
    newCursor = daSearchCursor(routesToDissolve, lrsKeyFieldList,
                               subsetSelectionQuery)
    uniqueLRSKeysDict = dict()
    for cursorRow in newCursor:
        uniqueLRSKeysDict[str(cursorRow[0])] = 1

    try:
        del newCursor
    except:
        pass

    uniqueLRSKeysList = uniqueLRSKeysDict.keys()
    try:
        uniqueLRSKeysList.remove('None')
    except:
        print(
            "Could not remove 'None' from the list of uniqueLRSKeys since it was not a part of the list."
        )

    print("LRSKey list creation successful.")
    print('Found ' + str(len(uniqueLRSKeysList)) +
          ' unique LRS Keys in the centerline data for this query:')
    print(str(subsetSelectionQuery))

    #Use multiSelection

    multiSelectionQueryBase = str(
        str(subsetSelectionQuery) + ''' AND ''' + ''' "''' + str(lrsKeyToUse) +
        '''" IS NOT NULL AND "''' + str(lrsKeyToUse) + '''" IN (''')
    multiSelectionQuery = multiSelectionQueryBase
    multiCounter = 0
    multiDissolveFields = [
        str(lrsKeyToUse), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
        'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
        'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L', 'KDOT_COUNTY_R'
    ]
    ##multiDissolveFields = str(lrsKeyToUse) + ';LRS_COUNTY_PRE;LRS_ROUTE_PREFIX;LRS_ROUTE_NUM;LRS_ROUTE_SUFFIX;LRS_UNIQUE_IDENT;LRS_UNIQUE_IDENT1'
    ##multiStatsFields = str(n1FromMeas) + " MIN;" + str(n1ToMeas) + " MAX"
    multiStatsFields = ""
    singlePart = "SINGLE_PART"
    unsplitLines = "UNSPLIT_LINES"

    # 3.) Loop through the list of unique LRS Keys
    for uniqueKeyItem in uniqueLRSKeysList:
        # Make a selection list that includes 50 keys, then select the keys and dissolve to make a new
        # feature class.
        # After the selection is dissolved, use a spatial select on the original feature class and
        # an attribute selection on the original feature class to see which original features should
        # be deleted.
        # Then, delete the selected features (if at least 1 selected).
        #
        try:
            Delete_management(dissolveOutFC)
        except:
            print("Could not delete the dissolveOutFC layer.")

        # 4.) For groups of 2000 LRS Keys, select all the features with those LRS Keys.
        if multiCounter <= 1999:
            multiSelectionQuery += """'""" + str(
                uniqueKeyItem) + """'""" + """, """
            multiCounter += 1
        else:
            # Add the current item, then
            multiSelectionQuery += """'""" + str(
                uniqueKeyItem) + """'""" + """, """
            # Remove the trailing ", " and add a closing parenthesis.
            multiSelectionQuery = multiSelectionQuery[:-2] + """) """
            SelectLayerByAttribute_management(fcAsFeatureLayerForDissolves,
                                              "NEW_SELECTION",
                                              multiSelectionQuery)
            # Have to do from step 5 on here also.

            ### -shouldbeafunctionblock#1- ###
            # 5.) Count selected features.
            countResult0 = GetCount_management(fcAsFeatureLayerForDissolves)
            intCount0 = int(countResult0.getOutput(0))
            if intCount0 >= 1:
                # 6.) Make a new layer or dissolved layer from this selection.
                Dissolve_management(fcAsFeatureLayerForDissolves,
                                    dissolveOutFC, multiDissolveFields,
                                    multiStatsFields, singlePart, unsplitLines)

                # 7.) Count the number of dissolved features.
                countResult1 = GetCount_management(dissolveOutFC)
                intCount1 = int(countResult1.getOutput(0))
                print('Counted ' + str(intCount1) +
                      ' features returned for that dissolve.')
                # 8a.) If the number of dissolved features is 0, then append the error to the error file
                #       and go on to the next LRS Key in the loop.
                if intCount1 == 0:
                    with open(dissolveErrorsFile, 'a') as errorFile:
                        errorFile.write(str(multiSelectionQuery))
                # 8b.) From the spatial select, select the subset of features that also have a matching LRS Key.
                else:
                    SelectLayerByAttribute_management(
                        fcAsFeatureLayerForDissolves, 'NEW_SELECTION',
                        multiSelectionQuery)
                    # 9.) Else, spatially select features in the original feature class with 'SHARE_A_LINE_SEGMENT_WITH'.
                    SelectLayerByLocation_management(
                        fcAsFeatureLayerForDissolves,
                        'SHARE_A_LINE_SEGMENT_WITH', dissolveOutFC, 0,
                        'SUBSET_SELECTION')
                    # 10.) Count to make sure that at least one feature is selected.
                    countResult2 = GetCount_management(
                        fcAsFeatureLayerForDissolves)
                    intCount2 = int(countResult2.getOutput(0))
                    print(
                        'There were ' + str(intCount2) +
                        ' features selected for replacement in the fcAsFeatureLayerForDissolves layer.'
                    )
                    if intCount2 >= 1:
                        # 11.) If so, cursor the features out of the dissolve layer.
                        featureList = list()
                        searchCursorFields = [
                            str(lrsKeyToUse), 'LRS_COUNTY_PRE',
                            'LRS_ROUTE_PREFIX', 'LRS_ROUTE_NUM',
                            'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
                            'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L',
                            'KDOT_COUNTY_R', 'SHAPE@'
                        ]
                        newCursor = daSearchCursor(dissolveOutFC,
                                                   searchCursorFields)

                        for cursorItem in newCursor:
                            featureList.append(list(cursorItem))

                        try:
                            del newCursor
                        except:
                            pass

                        # 12.) Delete the selected features in the input layer.
                        try:
                            DeleteFeatures_management(
                                fcAsFeatureLayerForDissolves)
                        except:
                            print(
                                "Could not delete features for the selection "
                                + str(multiSelectionQuery) + ".")
                        # 13.) Insert the features from the dissolve layer into the copy of the centerlines.
                        insertCursorFields = [
                            str(lrsKeyToUse), 'LRS_COUNTY_PRE',
                            'LRS_ROUTE_PREFIX', 'LRS_ROUTE_NUM',
                            'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
                            'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L',
                            'KDOT_COUNTY_R', 'SHAPE@'
                        ]
                        newCursor = daInsertCursor(
                            fcAsFeatureLayerForDissolves, insertCursorFields)

                        for featureItem in featureList:
                            newCursor.insertRow(featureItem)

                        try:
                            del newCursor
                        except:
                            pass
                        try:
                            del featureList
                        except:
                            pass
                    else:
                        pass
            multiSelectionQuery = ''' "''' + str(
                lrsKeyToUse) + '''" IS NOT NULL AND "''' + str(
                    lrsKeyToUse) + '''" IN ('''
            multiCounter = 0
            ### -shouldbeafunctionblock#1- ###

    # After the for loop, if there is still anything remaining which was unselected in the
    # the previous multiSelectionQuery steps.
    # Remove the trailing ", " and add a closing parenthesis.
    if multiSelectionQuery != multiSelectionQueryBase:
        multiSelectionQuery = multiSelectionQuery[:-2] + """) """
    else:
        # The selection query would not select anything.
        return
    SelectLayerByAttribute_management(fcAsFeatureLayerForDissolves,
                                      "NEW_SELECTION", multiSelectionQuery)

    # Then redo from step 5 on at the end of the loop IF there is anything left to select
    # which was not selected... so if selectionCounter != 0.

    ### -shouldbeafunctionblock#2- ###
    # 5.) Count selected features.
    countResult0 = GetCount_management(fcAsFeatureLayerForDissolves)
    intCount0 = int(countResult0.getOutput(0))
    if intCount0 >= 1:
        # 6.) Make a new layer or dissolved layer from this selection. -- Question about fields.
        Dissolve_management(fcAsFeatureLayerForDissolves, dissolveOutFC,
                            multiDissolveFields, multiStatsFields, singlePart,
                            unsplitLines)

        # 7.) Count the number of dissolved features.
        countResult1 = GetCount_management(dissolveOutFC)
        intCount1 = int(countResult1.getOutput(0))
        print('Counted ' + str(intCount1) +
              ' features returned for that dissolve.')
        # 8a.) If the number of dissolved features is 0, then append the error to the error file
        #       and go on to the next LRS Key in the loop.
        if intCount1 == 0:
            with open(dissolveErrorsFile, 'a') as errorFile:
                errorFile.write(str(multiSelectionQuery))
        # 8b.) From the spatial select, select the subset of features that also have a matching LRS Key.
        else:
            SelectLayerByAttribute_management(fcAsFeatureLayerForDissolves,
                                              'NEW_SELECTION',
                                              multiSelectionQuery)
            # 9.) Else, spatially select features in the original feature class with 'SHARE_A_LINE_SEGMENT_WITH'.
            SelectLayerByLocation_management(fcAsFeatureLayerForDissolves,
                                             'SHARE_A_LINE_SEGMENT_WITH',
                                             dissolveOutFC, 0,
                                             'SUBSET_SELECTION')
            # 10.) Count to make sure that at least one feature is selected.
            countResult2 = GetCount_management(fcAsFeatureLayerForDissolves)
            intCount2 = int(countResult2.getOutput(0))
            print(
                'There were ' + str(intCount2) +
                ' features selected in the fcAsFeatureLayerForDissolves layer.'
            )
            if intCount2 >= 1:
                # 11.) If so, cursor the features out of the dissolve layer.
                featureList = list()
                searchCursorFields = [
                    str(lrsKeyToUse), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
                    'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
                    'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L', 'KDOT_COUNTY_R',
                    'SHAPE@'
                ]
                newCursor = daSearchCursor(dissolveOutFC, searchCursorFields)

                for cursorItem in newCursor:
                    featureList.append(list(cursorItem))

                try:
                    del newCursor
                except:
                    pass

                # 12.) Delete the selected features in the input layer.
                try:
                    DeleteFeatures_management(fcAsFeatureLayerForDissolves)
                except:
                    print("Could not delete features for the selection " +
                          str(multiSelectionQuery) + ".")
                # 13.) Insert the features from the dissolve layer into the copy of the centerlines.
                insertCursorFields = [
                    str(lrsKeyToUse), 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
                    'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
                    'LRS_UNIQUE_IDENT1', 'KDOT_COUNTY_L', 'KDOT_COUNTY_R',
                    'SHAPE@'
                ]
                newCursor = daInsertCursor(fcAsFeatureLayerForDissolves,
                                           insertCursorFields)

                for featureItem in featureList:
                    newCursor.insertRow(featureItem)

                try:
                    del newCursor
                except:
                    pass
                try:
                    del featureList
                except:
                    pass
            else:
                pass
def main():
    # Do this by county.
    # Get a list of all of the available county numbers.
    # Then create an updateCursor for each county, using
    # a selection that looks at the LRS_COUNTY_PRE and LRS_PREFIX or existing KDOT_LRS_KEY.
    tempDesc = Describe(fcWithLocalRoutesToDissolveAndMeasure)
    print(
        "Updating the concatenated LRS Key Field and start/end measures for selected features in "
        + returnFeatureClass(tempDesc.catalogPath) + ".")
    OIDFieldName = str(tempDesc.OIDFieldName)

    try:
        del tempDesc
    except:
        pass

    uniqueCountyCodeDict = dict()
    countyCodeFieldsList = ['KDOT_COUNTY_L', 'KDOT_COUNTY_R']
    newCursor = daSearchCursor(fcWithLocalRoutesToDissolveAndMeasure,
                               countyCodeFieldsList)
    for cursorRow in newCursor:
        uniqueCountyCodeDict[str(cursorRow[0])] = 1
        uniqueCountyCodeDict[str(cursorRow[1])] = 1

    try:
        del newCursor
    except:
        pass

    uniqueCountyCodeList = list()

    for uniqueCountyCode in uniqueCountyCodeDict.keys():
        uniqueCountyCodeList.append(uniqueCountyCode)

    try:
        del uniqueCountyCodeDict
    except:
        pass

    try:
        uniqueCountyCodeList.remove('None')
    except:
        pass

    sortedUniqueCountyCodes = sorted(
        uniqueCountyCodeList
    )  # No need to specify a key since it's one column.

    for uniqueCountyCodeItem in sortedUniqueCountyCodes:
        print('Selecting features based on countyCode: ' +
              str(uniqueCountyCodeItem) + '.')
        routeFeaturesList = list()

        listOfFieldsToUse = [
            OIDFieldName, 'LRS_COUNTY_PRE', 'LRS_ROUTE_PREFIX',
            'LRS_ROUTE_NUM', 'LRS_ROUTE_SUFFIX', 'LRS_UNIQUE_IDENT',
            'LRS_UNIQUE_IDENT1', lrsKeyToUse
        ]

        # Modified from the original localroutenumbering sql to include an exception for '%W%' routes, because I don't think that those
        # were included in the localroutenumbering, even though they should have been.
        selectionQuery1 = """ KDOT_COUNTY_L = '""" + str(
            uniqueCountyCodeItem
        ) + """' AND (((KDOT_LRS_KEY IS NULL AND LRS_ROUTE_PREFIX = 'L') OR KDOT_LRS_KEY LIKE '%L%') AND NOT KDOT_LRS_KEY LIKE '%W%') """
        selectionQuery2 = """ KDOT_COUNTY_L IS NULL AND KDOT_COUNTY_R = '""" + str(
            uniqueCountyCodeItem
        ) + """' AND (((KDOT_LRS_KEY IS NULL AND LRS_ROUTE_PREFIX = 'L') OR KDOT_LRS_KEY LIKE '%L%') AND NOT KDOT_LRS_KEY LIKE '%W%') """

        newCursor = daUpdateCursor(fcWithLocalRoutesToDissolveAndMeasure,
                                   listOfFieldsToUse, selectionQuery1)
        for cursorRow in newCursor:
            cursorListItem = list(cursorRow)
            # change each cursorRow to a list
            # then pass the list to a function that concats the parts
            # into the LRS key field.
            concattedKeyListItem = concatTheLRSParts(cursorListItem,
                                                     uniqueCountyCodeItem)
            # Receive the list back and use it to update the
            # row.
            newCursor.updateRow(concattedKeyListItem)

        try:
            del newCursor
        except:
            pass

        newCursor = daUpdateCursor(fcWithLocalRoutesToDissolveAndMeasure,
                                   listOfFieldsToUse, selectionQuery2)
        for cursorRow in newCursor:
            cursorListItem = list(cursorRow)
            # change each cursorRow to a list
            # then pass the list to a function that concats the parts
            # into the LRS key field.
            concattedKeyListItem = concatTheLRSParts(cursorListItem,
                                                     uniqueCountyCodeItem)
            # Receive the list back and use it to update the
            # row.
            newCursor.updateRow(concattedKeyListItem)

        try:
            del newCursor
        except:
            pass

        # At this point, all of the local features in a county should have had
        # their LRS keys updated.
        # What we need to do now is to dissolve them based on LRS key.
        dissolveBasedOnLocalRouteKeys(fcWithLocalRoutesToDissolveAndMeasure,
                                      selectionQuery1)
        dissolveBasedOnLocalRouteKeys(fcWithLocalRoutesToDissolveAndMeasure,
                                      selectionQuery2)

        # At this point, all of the local featuers should be dissolved into
        # single part lines.
        # Go ahead and add the measures based on 0-to-shapelength.
        calculateMeasuresForLocalRoutes(fcWithLocalRoutesToDissolveAndMeasure,
                                        selectionQuery1)
        calculateMeasuresForLocalRoutes(fcWithLocalRoutesToDissolveAndMeasure,
                                        selectionQuery2)
Ejemplo n.º 21
0
def transferFeatures():
    env.workspace = in_memory
    featuresToTransfer = list()
    try:
        # Create an in_memory feature class which to hold the features from
        # the Oracle table.
        FeatureClassToFeatureClass_conversion(sdeCMLRS,"in_memory","CMLRS")
        
        #truncating CDRS segments in KanDrive Spatial
        print str(datetime.datetime.now()) + " truncating CMLRS segments in KanDrive Spatial."
        env.workspace = gdbCMLRSLocation
        TruncateTable_management(gdbCMLRSTable)
        env.workspace = in_memory
        
        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to both of the
        # tables and give it the same name in both.
        ###############################################################################################################
        
        # searchCursorFields go to r"in_memory\CMLRS". (Input table)(Indirect)
        Sde_CMLRS_Object = Describe(r"in_memory\CMLRS")
        Sde_CMLRS_Fields = [field.name for field in Sde_CMLRS_Object.fields]
        Gdb_CMLRS_Object = Describe(gdb_93_CMLRS)
        Gdb_CMLRS_Fields = [field.name for field in Gdb_CMLRS_Object.fields]
        
        # This Python list comprehension creates the intersection of the two *_Fields lists
        # and makes sure that the Shape field and Object ID fields are not directly
        # transfered. -- The 'SHAPE@' token indirectly transfers the geometry instead
        # and the Object ID of the target feature class is automatically calculated
        # by the insert cursor.
        searchCursorFields = [fieldName for fieldName in Sde_CMLRS_Fields if 
                              fieldName in Gdb_CMLRS_Fields and
                              fieldName != Sde_CMLRS_Object.OIDFieldName and
                              fieldName != Gdb_CMLRS_Object.OIDFieldName and
                              fieldName != 'Shape']
        
        searchCursorFields.append('SHAPE@')
        
        # Make the insertCursor use the same fields as the searchCursor.
        insertCursorFields = searchCursorFields
        
        print "fieldNames to be used in the searchCursor (and insertCursor):"
        for fieldName in searchCursorFields:
            print fieldName        
        
        CMLRS_SearchCursor = daSearchCursor(r"in_memory\CMLRS", searchCursorFields)
        
        for CMLRS_CursorItem in CMLRS_SearchCursor:
            featureItem = list(CMLRS_CursorItem)
            featuresToTransfer.append(featureItem)
        
        CMLRS_InsertCursor = daInsertCursor(gdb_93_CMLRS, insertCursorFields)
        
        for CMLRS_Feature in featuresToTransfer:
            insertOID = CMLRS_InsertCursor.insertRow(CMLRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)
        
    
    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement
        
        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging('Cansys_CMLRS_Transfer', 'SharedSDEProd.gdb\SHARED_CANSYS_CMLRS',
            scriptFailure, startTime, endTime, errorStatement, pythonLogTable)
            
        try:
            del errorItem
        except:
            pass
        
        # Reraise the error to stop execution and prevent a success message
        # from being inserted into the table.
        raise
        
    finally:
        try:
            del CMLRS_SearchCursor
        except:
            pass
        try:
            del CMLRS_InsertCursor
        except:
            pass
Ejemplo n.º 22
0
def createUniqueIdentifier():
    '''filters through records and calculates an incremental Unique Identifier for routes that are not border routes, to handle Y's, eyebrows, and splits that would cause complex routes'''
    workspaceLocation = gdb
    #MakeFeatureLayer_management(lyr,"RCL_Particles",where_clause="COUNTY_L = COUNTY_R AND STATE_L = STATE_R AND ( L_F_ADD =0 OR L_T_ADD =0 OR R_F_ADD =0 OR R_T_ADD =0)")
    featureClassName = lyr
    #from arcpy.da import SearchCursor as daSearchCursor, UpdateCursor as daUpdateCursor, Editor as daEditor
    alphabetListForConversion = [
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
        "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
    ]
    newCursor = daSearchCursor(featureClassName, uniqueIdInFields)
    searchList = list()
    for searchRow in newCursor:
        searchList.append(
            list(searchRow)
        )  # Transforms the row tuple into a list so it can be edited.

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

    matchCount = 0
    matchList = list()

    for testRow in searchList:
        if (testRow[1] == testRow[2] and testRow[3] == testRow[4]
                and (str(testRow[5]) == "0" or str(testRow[6]) == "0"
                     or str(testRow[7]) == "0" or str(testRow[8]) == "0")):
            matchCount += 1
            matchList.append(testRow)

    matchedRowDictionary = dict()

    for matchedRow in matchList:
        matchedRowContainer = list()
        # If the key already exists, assign the previous list of lists
        # to the list container, then append the new list
        # before updating the new value to that key in the dictionary.
        if matchedRow[10] in matchedRowDictionary:
            matchedRowContainer = matchedRowDictionary[matchedRow[10]]
            matchedRowContainer.append(matchedRow)
            matchedRowDictionary[matchedRow[10]] = matchedRowContainer
        # Otherwise, the key needs to be created
        # with the value, the list container, having only
        # one list contained within it for now.
        else:
            matchedRowContainer.append(matchedRow)
            matchedRowDictionary[matchedRow[10]] = matchedRowContainer

    for LRSKey in matchedRowDictionary:
        outRowContainer = matchedRowDictionary[LRSKey]
        # Sort based on length
        outRowContainer = sorted(outRowContainer,
                                 key=lambda sortingRow: sortingRow[11])
        countVariable = 0  # Start at 0 for unique values
        LRSVariable = ""
        for outRowIndex, outRow in enumerate(outRowContainer):
            # Is this the first list/row in the key's list container?
            # If so, then set the Resolution_Order to 0
            if outRowIndex == 0:
                outRow[9] = 0
            else:
                countVariable += 1
                if countVariable in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
                    outRow[9] = countVariable
                elif countVariable >= 10 and countVariable <= 34:
                    outRow[9] = alphabetListForConversion[
                        countVariable -
                        10]  # Converts countVariable to an alpha character, without the letter "O".
                else:
                    print "The count Variable is above 34. Ran out of numbers and letters to use as unique values."

            LRSVariable = outRow[10]
            LRSVariableShortened = str(
                LRSVariable[:-1]
            )  # Returns the LRSVariable without the last character.
            LRSVariable = LRSVariableShortened + str(outRow[9])
            outRow[10] = LRSVariable

            outRowString = ""

            for outRowElement in outRow:
                outRowString = outRowString + str(outRowElement) + " "

            print outRowString

            outRowContainer[outRowIndex] = outRow

        matchedRowDictionary[LRSKey] = outRowContainer

    newEditingSession = daEditor(workspaceLocation)
    newEditingSession.startEditing()
    newEditingSession.startOperation()

    newCursor = daUpdateCursor(featureClassName,
                               uniqueIdOutFields)  # @UndefinedVariable
    for existingRow in newCursor:
        formattedOutRow = list()
        if existingRow[2] in matchedRowDictionary.keys():
            outRowContainer = matchedRowDictionary[existingRow[2]]
            for outRow in outRowContainer:
                if existingRow[0] == outRow[
                        0]:  # Test for matching OBJECTID fields.
                    formattedOutRow.append(outRow[0])
                    formattedOutRow.append(outRow[9])
                    formattedOutRow.append(outRow[10])
                    newCursor.updateRow(formattedOutRow)
                else:
                    pass

        else:
            pass

    newEditingSession.stopOperation()
    newEditingSession.stopEditing(True)

    if "newCursor" in locals():
        del newCursor
    else:
        pass
Ejemplo n.º 23
0
def RoadinName(roadFeatures, nameExclusions):
    """This module corrects the road names in the soundex code where the road is named like Road A or Road 12 """
    # Need to add logic to remove the ST from roads like 3RD ST and make sure that this translates to 0003
    # and not 003.
    fieldList = ['OBJECTID', 'RD', 'Soundex']
    #Placeholder. Recompiled in nameExclusions for loop.
    listMatchString = re.compile(r'^WEST', re.IGNORECASE)
    roadNameString = ''
    roadPreSoundexString = ''
    roadSoundexString = ''
    holderList = list()

    testMatch0 = None
    testMatch1 = None
    testMatch2 = None
    testMatch3 = None

    # Get the data from the geodatabase so that it can be used in the next part of the function.
    cursor = daSearchCursor(roadFeatures, fieldList)  # @UndefinedVariable
    for row in cursor:
        listRow = list(row)
        holderList.append(listRow)

    # Clean up
    if "cursor" in locals():
        del cursor
    else:
        pass
    if "row" in locals():
        del row
    else:
        pass

    # Matches any group of 3 alpha characters in the string, ignoring case.
    tripleAlphaMatchString = re.compile(r'[A-Z][A-Z][A-Z]', re.IGNORECASE)
    # Matches 1 or 2 alpha characters at the start of a string, ignoring case.
    singleOrDoubleAlphaMatchString = re.compile(r'^[A-Z]$|^[A-Z][A-Z]$',
                                                re.IGNORECASE)
    # Matches 1 to 4 digits at the start of a string, probably no reason to ignore case in the check.
    singleToQuadNumberMatchString = re.compile(
        r'^[0-9]$|^[0-9][0-9]$|^[0-9][0-9][0-9]$|^[0-9][0-9][0-9][0-9]$')
    anyNumberMatchString = re.compile(r'[0-9]', re.IGNORECASE)

    # For roads that don't match a name exclusion:
    singleOrDoubleNumberThenAlphaMatchString = re.compile(
        r'^[0-9][0-9][A-Z]$|^[0-9][A-Z]$', re.IGNORECASE)
    # For roads that don't match a name exclusion and should be normally Numdexed.
    firstCharacterNumberString = re.compile(r'^[0-9]')

    ## Significant structure change here 2014-11-05.
    ## Watch for possible bugs.
    ##
    ## Added Numdex logic to this part, which
    ## caused some issues.
    ##
    ## Flattened the loops out here so that it only
    ## does a run through the
    ## <for heldRow in holderList>
    ## loop once instead of doing it once per
    ## entry in the nameExclusions list via
    ## <for excludedText in nameExclusions>
    ##
    ## Runs faster now. After changing the regex string
    ## to be dynamically generated prior to compilation
    ## and using \b{0}\b as part of the pattern,
    ## errors *seem* to be gone.

    stringToCompile = ""

    # Perform some regex on the strings to produce a new soundex in certain cases.
    for i, excludedText in enumerate(nameExclusions):  #shift left start
        excludedText = str(excludedText)
        excludedText = excludedText.upper()
        #listMatchString = re.compile(r'^{0}\s'.format(re.escape(excludedText)), re.IGNORECASE) ## Old version, pre-dynamic generation.
        if i == 0:
            stringToCompile = r'^\b{0}\b\ '.format(re.escape(excludedText))
        else:
            stringToCompile = stringToCompile + r'|^\b{0}\b\ '.format(
                re.escape(excludedText))
        print i
        listMatchString = re.compile(stringToCompile, re.IGNORECASE)

    print "stringToCompile = " + str(stringToCompile)

    for heldRow in holderList:
        roadNameString = ''
        roadPreSoundexString = ''
        roadSoundexString = ''

        roadNameString = str(heldRow[1])
        roadNameString = roadNameString.upper()
        roadNameString = roadNameString.replace(".", "")

        exclusionMatch = listMatchString.search(roadNameString)
        if exclusionMatch != None:  # Testing for excluded Road Names such as "Road" and "CR" in "Road 25" and "CR 2500".
            # Get the characters from the end of the testMatch to the end of the string.
            # Should return a string that starts with a space.

            roadPreSoundexString = roadNameString[exclusionMatch.end():]

            # Replace with a search for " " by group in regex.
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")
            # then loop through the groups to replace with "" so that any number
            # of spaces can be removed.

            print "roadNameString = " + str(roadNameString)
            print "roadPreSoundexString = " + str(roadPreSoundexString)

            # Do subbing for #ST, #ND, #RD, #TH etc...
            for numberEnding in ordinalNumberEndings:
                nonsensitiveReplace = re.compile(r'[0-9]{0}'.format(
                    re.escape(numberEnding), re.IGNORECASE))
                replaceMatch = nonsensitiveReplace.search(roadNameString)
                if replaceMatch != None:
                    roadPreSoundexString = re.sub(replaceMatch.group(0), "",
                                                  roadPreSoundexString)
                else:
                    pass

            # Replace with regex string that matches spaces as groups, then loop through groups to replace.
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")

            testMatch0 = None
            testMatch0 = tripleAlphaMatchString.search(roadPreSoundexString)
            testMatch1 = None
            testMatch1 = singleOrDoubleAlphaMatchString.search(
                roadPreSoundexString)
            testMatch2 = None
            testMatch2 = singleToQuadNumberMatchString.search(
                roadPreSoundexString)
            testMatch3 = None
            testMatch3 = anyNumberMatchString.search(roadPreSoundexString)

            if testMatch0 != None:
                roadSoundexString = soundex(roadPreSoundexString)
                # Slice the roadSoundexString to remove the first character, but keep the rest.
                if len(roadSoundexString) >= 4:
                    roadSoundexString = roadSoundexString[1:4]
                    # The next line looks complicated, but exclusionMatch.group(0)[0:1]
                    # is actually just getting the first letter of the first matched pattern.
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                elif len(roadSoundexString) == 3:
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                elif len(roadSoundexString) == 2 or len(
                        roadSoundexString) == 1:
                    roadSoundexString = roadSoundexString.zfill(3)
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                else:
                    pass

                heldRow[2] = roadSoundexString

            elif testMatch1 != None:  # Road A, Road BB, or similar.
                roadPreSoundexString = roadPreSoundexString[testMatch1.start(
                ):testMatch1.end()]
                if len(roadPreSoundexString) > 2:
                    pass
                elif len(roadPreSoundexString) == 2:
                    roadSoundexString = "0" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 1:
                    roadSoundexString = "00" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                else:
                    pass

            elif testMatch2 != None:
                roadPreSoundexString = roadPreSoundexString[testMatch2.start(
                ):testMatch2.end()]
                if len(roadPreSoundexString) > 4:
                    pass
                elif len(roadPreSoundexString) == 4:
                    # Slice the string to include only the first 3 characters, as slice end is non-inclusive.
                    roadSoundexString = roadPreSoundexString[:4]
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 3:
                    roadSoundexString = roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 2:
                    roadSoundexString = "0" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 1:
                    roadSoundexString = "00" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(
                        0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                else:
                    pass
            else:
                pass

        else:
            roadNameString = heldRow[1]
            testMatch4 = None
            testMatch4 = singleOrDoubleNumberThenAlphaMatchString.search(
                roadNameString)
            testMatch5 = None
            testMatch5 = firstCharacterNumberString.search(roadNameString)

            # Numdex with one or two numbers, then alpha.
            if testMatch4 != None:
                roadPreSoundexString = roadNameString[testMatch4.start():]
                roadSoundexString = roadPreSoundexString.zfill(4)
                heldRow[2] = roadSoundexString
            # Normal Numdex if there were not one or two numbers, then alpha, but the string starts with a number.
            elif testMatch5 != None:
                numerical_re = re.compile("[A-Z]|[^0-9][^0-9][^0-9][^0-9]")

                roadPreSoundexString = roadNameString.replace(" ", "")
                roadSoundexString = re.sub(numerical_re, "",
                                           roadPreSoundexString.zfill(4))

                if len(roadSoundexString) > 4:
                    roadSoundexString = roadSoundexString[:5]
                else:
                    pass

                roadSoundexString = roadSoundexString.zfill(4)

                heldRow[2] = roadSoundexString

            else:  # Check for AA, BB, EE, etc without an excluded name in front of it
                if len(roadNameString) == 2:
                    if roadNameString[0] == roadNameString[1]:
                        roadPreSoundexString = roadNameString
                        roadSoundexString = roadPreSoundexString.zfill(4)
                else:  # Normal Soundex
                    roadPreSoundexString = roadNameString
                    roadSoundexString = soundex(roadPreSoundexString)

                heldRow[2] = roadSoundexString  # shift left end

    try:
        # Start an edit session for this workspace because the centerline
        # feature class participates in a topology.
        editSession = daEditor(gdb)
        editSession.startEditing(False, False)
        editSession.startOperation()

        print "Editing started."

        cursor = daUpdateCursor(roadFeatures, fieldList)  # @UndefinedVariable
        for row in cursor:
            for heldRow in holderList:  # N^2 looping, try not to place print statements inside this block.
                if str(row[0]) == str(heldRow[0]):
                    cursor.updateRow(heldRow)
                else:
                    pass

        editSession.stopOperation()
        editSession.stopEditing(True)

        print "Editing complete."

    except Exception as e:
        print "Failed to update the Soundex values."
        print e.message
        print GetMessages(2)

    finally:
        # Clean up
        if "cursor" in locals():
            del cursor
        else:
            pass
        if "row" in locals():
            del row
        else:
            pass
Ejemplo n.º 24
0
def Kdot_RouteNameCalc():
    AliasTablePath = os.path.join(gdb, Alias)
    cursorFields = ["OBJECTID", "A_RD", "KDOT_ROUTENAME"]
    sCursor = daSearchCursor(AliasTablePath, cursorFields)
    searchDict = dict()
    print "In Kdot_RouteNameCalc..."
    for foundRow in sCursor:
        searchDict[foundRow[0]] = list(foundRow) # Transforms the row tuple into a list so it can be edited.
        print str(foundRow[0]) + "\t" + str(foundRow[1])
        
    try:
        del sCursor
    except:
        pass
    
    # Matches an I, U, or K at the start of the string, ignoring case.
    IUKMatchString = re.compile(r'^[IUK]', re.IGNORECASE)
    
    # Matches 1 to 3 digits at the end of a string, probably no reason to ignore case in the check.
    singleToTripleNumberEndMatchString = re.compile(r'[0-9][0-9][0-9]|[0-9][0-9]|[0-9]')     
    
    # Probably need to use regular expressions here.
    # Yes, rebuild with regex. Too many problems just trying to slice the strings.
    for keyName in searchDict:
        firstPart = ""
        secondPart = ""
        fullRouteName = ""
        listItem = searchDict[keyName]
        listItemRD = listItem[1]
        
        testResult0 = None
        testResult1 = None
        
        ####################################################################################
        
        testResult0 = re.search(IUKMatchString, listItemRD)
        testResult1 = re.search(singleToTripleNumberEndMatchString, listItemRD)        
        
        ####################################################################################
        
        if testResult0 is not None and testResult1 is not None:
            print "Found matches."
            firstPart = str(testResult0.group(0))
            secondPart = str(testResult1.group(0))
            
            # Pad the string with prepended zeroes if it is not 3 digits long already.
            if len(secondPart) == 2:
                secondPart = secondPart.zfill(3)
                print "secondPart = " + secondPart
            elif len(secondPart) == 1:
                secondPart = secondPart.zfill(3)
                print "secondPart = " + secondPart
            else:
                pass
            
            fullRouteName = firstPart + secondPart
            
            listItem[2] = fullRouteName
            searchDict[keyName] = listItem
            
            print "Resulting RouteName = " + str(listItem[2]) + "."
        else:
            print "Did not find matches."
            fullRouteName = firstPart + secondPart
            
            listItem[2] = fullRouteName
            searchDict[keyName] = listItem
    
    uCursor = daUpdateCursor(AliasTablePath, cursorFields)
    for uCursorItem in uCursor:
        for keyName in searchDict:
            listItem = searchDict[keyName]
            if uCursorItem[0] == listItem[0]:
                print "ObjectIDs matched: " + str(uCursorItem[0]) + " & " + str(listItem[0])
                print "The road name (for updateCursor) is: " + str(listItem[1])
                uCursor.updateRow(listItem)
                if listItem[2] is not None and listItem[2] != "":
                    print "The routeNameFull is: " + str(listItem[2])
                else:
                    print "RouteNameFull is None/Null/Empty. =("
            else:
                pass
    
    try:
        del uCursor
    except:
        pass
def exportErrorsToFeatureClasses(reviewTable, originGDB, errorOutputGDB,
                                 errorOutputGDBFolder):
    # Checking to see if the output already exists.
    # If so, remove it.
    if Exists(errorOutputGDB):
        Delete_management(errorOutputGDB)
    else:
        pass

    CreateFileGDB_management(errorOutputGDBFolder,
                             returnGDBOrSDEName(errorOutputGDB))

    previousWorkspace = env.workspace
    env.workspace = errorOutputGDB

    tableFields = ['ORIGINTABLE', 'CHECKTITLE', 'OBJECTID']
    newCursor = daSearchCursor(reviewTable, tableFields)

    revRows = list()

    for rowItem in newCursor:
        revRows.append(list(rowItem))

    try:
        del newCursor
    except:
        pass

    originTableList = list()
    checkTitleList = list()

    for revRowItem in revRows:
        originTableList.append(revRowItem[0])
        checkTitleList.append(revRowItem[1])

    print('Creating sets from the originTable and checkTitle lists.')
    originTableSet = set(originTableList)
    checkTitleSet = set(checkTitleList)
    print('Finished set creation.')

    originTableList = list(originTableSet)
    checkTitleList = list(checkTitleSet)

    tableAndCheckDataObjects = list()
    csvDictOfErrorFeatures = dict()

    for originTableItem in originTableList:
        print('Origin table = ' + originTableItem + '.')
        completeOriginTablePath = os.path.join(originGDB, originTableItem)
        print('The full path to the origin table is ' +
              str(completeOriginTablePath) + '.')
        tableViewName = "ReviewTable_View_" + str(originTableItem)
        originTableWhereClause = """"ORIGINTABLE" = '""" + str(
            originTableItem) + """'"""
        try:
            Delete_management(tableViewName)
        except:
            pass
        MakeTableView_management(reviewTable, tableViewName,
                                 originTableWhereClause)

        for checkTitleItem in checkTitleList:
            print('Check title = ' + checkTitleItem + '.')
            selectionWhereClause = """"CHECKTITLE" = '""" + str(
                checkTitleItem) + """'"""
            SelectLayerByAttribute_management(tableViewName, "NEW_SELECTION",
                                              selectionWhereClause)
            countResult = GetCount_management(tableViewName)
            intCount = int(countResult.getOutput(0))

            if intCount >= 1:
                tempTableAndCheckData = tableAndCheckData(
                    originTableItem, checkTitleItem)
                tableViewFields = ["RECORDID", "OBJECTID"]

                newCursor = daSearchCursor(tableViewName, tableViewFields,
                                           selectionWhereClause)

                newOIDList = list()

                for cursorItem in newCursor:
                    newOIDList.append(cursorItem[1])

                try:
                    del newCursor
                except:
                    pass

                tempTableAndCheckData.listOfOIDsToUse = newOIDList

                tableAndCheckDataObjects.append(tempTableAndCheckData)
            else:
                print("There were no features selected for the " +
                      tableViewName + " table.")

    print("There are " + str(len(tableAndCheckDataObjects)) +
          " different items in the tableAndCheckDataObjects list.")

    for listObject in tableAndCheckDataObjects:

        featureLayerForErrorOutput = 'FeatureClassAsFeatureLayer'

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

        fullPathToFeatureClass = os.path.join(originTablesGDB,
                                              listObject.tableName)

        MakeFeatureLayer_management(fullPathToFeatureClass,
                                    featureLayerForErrorOutput)

        # build the selection list & select up to but not more than 999 features at at time
        OIDTotalCounter = 0
        errorOutputWhereClause = """ "OBJECTID" IN ("""

        for errorOID in listObject.listOfOIDsToUse:
            if OIDTotalCounter <= 998:
                errorOutputWhereClause = errorOutputWhereClause + str(
                    errorOID) + """, """
                OIDTotalCounter += 1
            else:
                # Remove the trailing ", " and add a closing parenthesis.
                errorOutputWhereClause = errorOutputWhereClause[:-2] + """) """
                SelectLayerByAttribute_management(featureLayerForErrorOutput,
                                                  "ADD_TO_SELECTION",
                                                  errorOutputWhereClause)

                OIDTotalCounter = 0
                errorOutputWhereClause = """ "OBJECTID" IN ("""
                errorOutputWhereClause = errorOutputWhereClause + str(
                    errorOID) + """, """

        # Remove the trailing ", " and add a closing parenthesis.
        errorOutputWhereClause = errorOutputWhereClause[:-2] + """) """
        SelectLayerByAttribute_management(featureLayerForErrorOutput,
                                          "ADD_TO_SELECTION",
                                          errorOutputWhereClause)

        ##print "Counting..."
        selectedErrorsResult = GetCount_management(featureLayerForErrorOutput)
        selectedErrorsCount = int(selectedErrorsResult.getOutput(0))

        # export the selected data with the correct tableName & checkTitle
        outputFeatureClassName = formatCheckTitle(
            listObject.checkTitle) + "ErrorsFrom_" + listObject.tableName
        fullPathToOutputFeatureClass = os.path.join(errorOutputGDB,
                                                    outputFeatureClassName)

        csvDictOfErrorFeatures[outputFeatureClassName] = str(
            selectedErrorsCount)

        print(
            str(selectedErrorsCount) + "\t features will be written to \t" +
            outputFeatureClassName)
        if selectedErrorsCount >= 1:
            CopyFeatures_management(featureLayerForErrorOutput,
                                    fullPathToOutputFeatureClass)
            time.sleep(25)
            AddField_management(outputFeatureClassName, "OptionalInfo", "TEXT",
                                "", "", 250, "ReviewingInfo", nullable)
        else:
            pass

    # Need to write a short CSV here that tells the number and type of errors.
    print('Writing error information to an error reports file called ' +
          str(errorReportCSVName) + '.')
    try:
        with open(errorReportCSV, 'w') as fHandle:
            for errorFeature in errorReportRowsOrder:
                if errorFeature in csvDictOfErrorFeatures:
                    errorFeatureCount = csvDictOfErrorFeatures[errorFeature]
                    fHandle.write(
                        str(errorFeature) + ', ' + str(errorFeatureCount) +
                        '\n')
                else:
                    fHandle.write(str(errorFeature) + ', ' + str(0) + '\n')
            # Add a blank line to match previous formatting.
            fHandle.write('\n')
    except:
        print("There was an error writing to the file.")

    # Modify this so that it just checks for the existence of the roads
    # and highways check output, rather than relying on the config
    # file for whether or not this should be ran.
    # The config file can tell the full process whether or not
    # to run the R&H check, but the error report should give
    # details on the R&H check whether or not the config file
    # currently states that the R&H check should be ran again
    # were the full process to run.

    env.workspace = previousWorkspace
def labelAngleNormalization(quarterOrHalf):

    if quarterOrHalf.lower() == "quarter":
        countyBorderFeature = countyBorderFeature_Q
        countyRoadNameRosette = countyRoadNameRosette_Q
    elif quarterOrHalf.lower() == "half":
        countyBorderFeature = countyBorderFeature_H
        countyRoadNameRosette = countyRoadNameRosette_H
    else:
        print "quarterOrHalf variable not correctly defined."
        raise (Exception("quarterOrHalf error."))

    print "Normalizing the label angle values."

    if "COUNTY_NAME" not in ListFields(countyRoadNameRosette):
        AddField_management(countyRoadNameRosette, "COUNTY_NAME", "TEXT", "",
                            "", "55")
    else:
        pass

    newCursor = daSearchCursor(countyBorderFeature, countyBorderFields)

    countyTranslationDictionary = dict()

    # countyBorderItem[3] is the number, countyBorderItem[2] is the name.
    # -- Use for translating from county number to county name.
    for countyBorderItem in newCursor:
        if countyBorderItem[3] not in countyTranslationDictionary:
            countyTranslationDictionary[
                countyBorderItem[3]] = countyBorderItem[2]
        else:
            pass

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

    newCursor = daUpdateCursor(countyRoadNameRosette,
                               countyRoadNameRosetteFields)

    for countyPointItem in newCursor:
        countyPointItem = list(countyPointItem)

        # Takes the remainder of the angle divided by 360.
        # Uses fmod due to floating point issues with the normal modulo operator in python.
        countyPointItem[0] = math.fmod(countyPointItem[0], 360)

        # countyPointItem[1] is County Name, countyPointItem[2] is County Number.
        if countyPointItem[0] >= 250 and countyPointItem[0] <= 290:
            countyPointItem[0] = 270
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[
                    countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)

        elif countyPointItem[0] >= 160 and countyPointItem[0] <= 200:
            countyPointItem[0] = 180
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[
                    countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)

        elif countyPointItem[0] >= 70 and countyPointItem[0] <= 110:
            countyPointItem[0] = 90
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[
                    countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)

        elif (countyPointItem[0] >= 0
              and countyPointItem[0] <= 20) or (countyPointItem[0] >= 340
                                                and countyPointItem[0] <= 360):
            countyPointItem[0] = 0
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[
                    countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)

        else:
            print "Deleting a row for having an angle more than 20 degrees away from a cardinal direction."
            newCursor.deleteRow()

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

    print "Label angle normalization complete!"
    print "Done extending and intersecting road features."  # Need to break this into two pieces and pass some of the inmemorylayers
def duplicateNameRemoval(quarterOrHalf):

    if quarterOrHalf.lower() == "quarter":
        countyRoadNameRosette = countyRoadNameRosette_Q
    elif quarterOrHalf.lower() == "half":
        countyRoadNameRosette = countyRoadNameRosette_H
    else:
        print "quarterOrHalf variable not correctly defined."
        raise (Exception("quarterOrHalf error."))

    print "Starting duplicate name removal."

    countyRoadNameRosetteFields = ListFields(countyRoadNameRosette)

    print "countyRoadNameRosetteFields: "

    for fieldItem in countyRoadNameRosetteFields:
        print str(fieldItem.name)

    newCursor = daSearchCursor(countyRoadNameRosette,
                               countyRoadNameRosetteFieldsObjShape)

    # Debug only
    #print "Created a new cursor..."

    countyNamePointList = list()

    for eachPoint in newCursor:
        countyNamePointList.append(eachPoint)

    try:
        del newCursor
    except:
        pass

    # Debug only
    #print "Completed using the new cursor."

    pointDeleteList = list()

    for pointItem in countyNamePointList:
        for pointToCheck in countyNamePointList:
            # If the points share a road name, and a county number, but not the same ObjectID...
            if pointItem[0] not in pointDeleteList:
                if pointItem[3] == pointToCheck[3] and str(
                        pointItem[2]).upper() == str(
                            pointToCheck[2]).upper() and (not pointItem[0]
                                                          == pointToCheck[0]):
                    # Use the distance formula to check to see if these points are within a
                    # certain distance from one another.
                    # If so, add the pointToCheck to the pointDeleteList.
                    distance = 0
                    point1 = pointItem[1]
                    point2 = pointToCheck[1]

                    distance = calcPointDistance(point1, point2)

                    # Change this to add just the objectid to the pointDeleteList
                    # instead of the whole point row to increase the speed
                    # of the check when the list grows to a decent size.
                    # Distance of 10000 seems to give good results.
                    if distance >= 0 and distance < 10000 and pointToCheck[
                            0] not in pointDeleteList:
                        pointDeleteList.append(pointToCheck[0])
                    else:
                        pass
                else:
                    pass
            else:
                pass

    newCursor = daUpdateCursor(countyRoadNameRosette,
                               countyRoadNameRosetteFieldsObjShape)

    for updateableRow in newCursor:
        for pointToDeleteOID in pointDeleteList:
            if updateableRow[0] == pointToDeleteOID:
                print "Selected a point for " + str(
                    updateableRow[2]) + " in " + str(
                        updateableRow[4]) + " county to delete."
                newCursor.deleteRow()
                print "Point deleted."
            else:
                pass
        #updateCursor
        #delete pointToDelete from countyRoadNameRosette.
        #print a message saying that the point was deleted.

    try:
        del newCursor
    except:
        pass
Ejemplo n.º 28
0
def bufferCrashLocationAndIntersectWithRoads(crashObject, roadsLayer,
                                             outputIncrementInt,
                                             bufferAndIntersectSR,
                                             useParseMatchAddr):
    #pointToBufferXY = list(crashObject.initialShapeXY)
    #print("The crashObject.initialShapeXY is " + str(crashObject.initialShapeXY) + " and the pointToBufferXY is " + str(pointToBufferXY) + ".")
    ##pointToBufferWithoutGeometry = Point(pointToBufferXY)
    ##pointToBuffer = PointGeometry(pointToBufferXY, bufferAndIntersectSR)
    pointToBuffer = crashObject.initialShape
    offsetDistance = crashObject.offsetDistance

    # Perform layer selection here, then
    # intersect the buffer with the selected roads.

    roadNameColumns = crashObject.roadNameColumns

    accidentClusterTolerance = 2

    print(
        "Attempting to buffer and offset the crashObject with a unique key of: "
        + str(crashObject.uniqueKey) + ".")
    print("Using the roadNameColumns of: " + str(roadNameColumns) + ".")

    singlePartOffsetFeaturesList = list()

    try:
        if offsetDistance >= 5:
            ## Was previously failing here due to not having the name for intermediateAccidentBuffer
            offsetDistanceString = str(offsetDistance) + " Feet"
            Buffer_analysis(pointToBuffer, intermediateAccidentBuffer,
                            offsetDistanceString, "", "", "", "", "PLANAR")

            if debugOutputValue == True:
                # Save the buffer here. Call it bufferOutput_001 to start with, and increment from there. Get the number
                # from the calling script.
                bufferOutputLocation = bufferOutputLocationBase + "_" + str(
                    outputIncrementInt).zfill(4)
                copyFCToTempLocation(intermediateAccidentBuffer,
                                     bufferOutputLocation)
            else:
                pass

            firstRoadName = str(crashObject.onRoad)
            firstRoadName = firstRoadName.upper()

            roadNameValues = [firstRoadName]

            if useParseMatchAddr == True:
                parsedRoadNamesList = ParseMatchAddr(crashObject.matchAddress)
                secondRoadName = " "
                try:
                    secondRoadName = parsedRoadNamesList[0]
                    secondRoadName = secondRoadName.upper()
                except:
                    pass
                thirdRoadName = " "
                try:
                    thirdRoadName = parsedRoadNamesList[1]
                    thirdRoadName = thirdRoadName.upper()
                except:
                    pass

                roadNameValues = [firstRoadName, secondRoadName, thirdRoadName]
            else:
                pass

            streetWhereClause = generateWhereClause(roadNameColumns,
                                                    roadNameValues)
            print("The generated whereClause is: " + str(streetWhereClause) +
                  ".")
            SelectLayerByAttribute_management(roadsLayer, "NEW_SELECTION",
                                              streetWhereClause)

            selectionCount = str(GetCount_management(roadsLayer))

            if Exists(intermediateAccidentIntersect):
                try:
                    Delete_management(intermediateAccidentIntersect)
                except:
                    pass
            else:
                pass

            if int(selectionCount) != 0:
                featuresToIntersect = [roadsLayer, intermediateAccidentBuffer]
                Intersect_analysis(featuresToIntersect,
                                   intermediateAccidentIntersect, "ALL",
                                   accidentClusterTolerance, "POINT")

                time.sleep(0.25)
                # Wait a moment for the FC to settle.
                # And yes, it is ridiculous that the Intersect_analysis function would return without
                # its output being there and ready to use, but... *ahem*.
                # If it doesn't exist despite having been just created, then skip to the next record.
                if not (Exists(intermediateAccidentIntersect)):
                    print("There was no output from Intersect_analysis.")
                    crashObject.singlePartOffsetFeaturesList = None
                    return crashObject
                else:
                    pass

                if debugOutputValue == True:
                    # Save the intersect FC here. Call it intersectOutput_001 to start with, and increment from there. Get the number
                    # from the calling script.
                    intersectOutputLocation = intersectOutputLocationBase + "_" + str(
                        outputIncrementInt).zfill(4)
                    copyFCToTempLocation(intermediateAccidentIntersect,
                                         intersectOutputLocation)
                else:
                    pass

                # GetCount_management is not particularly Pythonic.
                countResult = GetCount_management(
                    intermediateAccidentIntersect)
                if int(countResult.getOutput(0)) > 0:
                    MultipartToSinglepart_management(
                        intermediateAccidentIntersect,
                        intermediateAccidentIntersectSinglePart)

                    # Maybe add a feature class to contain all of the single part points that get generated in multipart to singlepart.
                    singlePartsCursor = daSearchCursor(
                        intermediateAccidentIntersectSinglePart,
                        ['SHAPE@', 'SHAPE@XY'])
                    for singlePartRow in singlePartsCursor:
                        ##KDOTXYFieldsList = ['OBJECTID', 'STATUS', 'POINT_X', 'POINT_Y', 'ACCIDENT_KEY', 'ON_ROAD_KDOT_NAME',
                        ##                      'AT_ROAD_KDOT_DIRECTION', 'AT_ROAD_KDOT_DIST_FEET', 'AT_ROAD_KDOT_NAME',
                        ##                       'Match_addr']
                        print("The singlePartRow value is: " +
                              str(singlePartRow) + ".")
                        print(
                            "The singlePartRow[1][0] and singlePartRow[1][1] values are: "
                            + str(singlePartRow[1][0]) + " and " +
                            str(singlePartRow[1][1]) + ".")
                        print(
                            "The crashObject.initialShapeXY[0] and crashObject.initialShapeXY[1] values are: "
                            + str(crashObject.initialShapeXY[0]) + " and " +
                            str(crashObject.initialShapeXY[1]) + ".")
                        singlePartListItem = [
                            crashObject.initialShapeXY[0],
                            crashObject.initialShapeXY[1], singlePartRow[1][0],
                            singlePartRow[1][1], singlePartRow[0]
                        ]
                        #Previously used, but no longer necessary = , geocodedAccident[0]]
                        singlePartOffsetFeaturesList.append(singlePartListItem)

                    try:
                        del singlePartsCursor
                    except:
                        pass
                else:
                    print(
                        "There were zero output features counted in the intermediateAccidentIntersect feature class."
                    )
                    crashObject.singlePartOffsetFeaturesList = None
                    return crashObject
            else:
                pass  # Zero road segments selected. Will not attempt to offset.
        else:
            print(
                "This should have been caught by the lowOrZeroDistanceOffsetCheck function, but the accidentDistanceOffset is not >= 5."
            )
    except:
        print "WARNING:"
        print "An error occurred which prevented the crash point with Acc_Key: " + str(
            crashObject.uniqueKey)
        print "from being buffered and/or offset properly."
        print(traceback.format_exc())

    crashObject.singlePartOffsetFeaturesList = singlePartOffsetFeaturesList

    return crashObject
Ejemplo n.º 29
0
def duplicateCheckForMAndC():
    print(
        "Checking for duplicate route numbers in the target route numbers for R, M, and C Routes."
    )
    # Select the R routes.
    # Cursor them, and add their route number to a dict.
    # Then, select the M routes.
    # Cursor them and add their route number to a dict.
    # Then, select the C routes.
    # Cursor them and add their route number to a dict.
    # Create a list of free route numbers that are not in any of the 3 dicts.
    # Then, for each M route, if its routenumber is not in the R routes dict,
    # mark the M route's targetRouteNumChanged to "Kept".
    # Otherwise, if its routenumber is in the R routes dict,
    # Select the next free route number in the free route numbers list.
    # Remove the free route number from the free route numbers list.
    # Assign the free route number to the M route and mark the M route's
    # targetRouteNumChanged to "Changed".
    # Then, for each C route, if its routenumber is not in the R routes dict
    # and if it is also not in the M routes dict,
    # mark the C route's targetRouteNumChanged to "Kept".
    # Otherwise, if its routenumber is in the R routes dict or the M routes dict,
    # Select the next free route number in the free route numbers list.
    # Remove the free route number from the free route numbers list.
    # Assign the free route number to the C route and mark the C route's
    # targetRouteNumChanged to "Changed".
    rRoutesDict = dict()
    mRoutesDict = dict()
    cRoutesDict = dict()

    rRoutesSelectionQuery = """ SourceRouteId LIKE '___R%' OR LRS_ROUTE_PREFIX = 'R' """
    mRoutesSelectionQuery = """ SourceRouteId LIKE '___M%' OR LRS_ROUTE_PREFIX = 'M' """
    cRoutesSelectionQuery = """ SourceRouteId LIKE '___C%' OR LRS_ROUTE_PREFIX = 'C' """

    searchCursorFields = [
        sourceRouteNum, targetRouteNum, targetRouteNumChanged
    ]

    newCursor = daSearchCursor(fcToCalculateTargetKeysIn, searchCursorFields,
                               rRoutesSelectionQuery)
    for cursorItem in newCursor:
        rRoutesDict[cursorItem[-3]] = 1
    try:
        del newCursor
    except:
        pass

    newCursor = daSearchCursor(fcToCalculateTargetKeysIn, searchCursorFields,
                               mRoutesSelectionQuery)
    for cursorItem in newCursor:
        mRoutesDict[cursorItem[-3]] = 1
    try:
        del newCursor
    except:
        pass

    newCursor = daSearchCursor(fcToCalculateTargetKeysIn, searchCursorFields,
                               cRoutesSelectionQuery)
    for cursorItem in newCursor:
        cRoutesDict[cursorItem[-3]] = 1
    try:
        del newCursor
    except:
        pass

    usedRoutesList = [x for x in rRoutesDict.keys()]
    usedRoutesList = usedRoutesList + [y for y in mRoutesDict.keys()]
    usedRoutesList = usedRoutesList + [z for z in cRoutesDict.keys()]
    sortedUsedRoutesList = sorted(usedRoutesList)
    freeRoutesList = [
        str(x).zfill(5) for x in xrange(12000, 64000)
        if str(x).zfill(5) not in sortedUsedRoutesList
    ]

    print("Used routes are as follows:")
    for usedRouteNumber in sortedUsedRoutesList:
        print("Used route number = " + str(usedRouteNumber) + ".")

    sortedFreeRoutesList = sorted(freeRoutesList)
    reverseSortedFreeRoutesList = sortedFreeRoutesList[::-1]

    print(
        "Updating lrs target numbers for M routes where they conflict with R routes."
    )
    # Check the target lrs route numbers for M routes against the R routes.
    rRoutesKeys = rRoutesDict.keys()
    newCursor = daUpdateCursor(fcToCalculateTargetKeysIn, searchCursorFields,
                               mRoutesSelectionQuery)
    for mRouteItem in newCursor:
        mRouteListItem = list(mRouteItem)
        if mRouteListItem[-2] in rRoutesKeys:
            mRouteListItem[-1] = 'Changed'
            mRouteListItem[-2] = reverseSortedFreeRoutesList.pop()
            mRoutesDict[mRouteListItem[-2]] = 1
            newCursor.updateRow(mRouteListItem)
        else:
            pass
    try:
        del newCursor
    except:
        pass

    print(
        "Updating lrs target numbers for C routes where they conflict with R routes or M routes."
    )
    # Check the target lrs route numbers for C routes against the R routes and the M routes.
    mRoutesKeys = mRoutesDict.keys()
    newCursor = daUpdateCursor(fcToCalculateTargetKeysIn, searchCursorFields,
                               cRoutesSelectionQuery)
    for cRouteItem in newCursor:
        cRouteListItem = list(cRouteItem)
        if cRouteListItem[-2] in rRoutesKeys or cRouteListItem[
                -2] in mRoutesKeys:
            cRouteListItem[-1] = 'Changed'
            cRouteListItem[-2] = reverseSortedFreeRoutesList.pop()
            newCursor.updateRow(cRouteListItem)
        else:
            pass
    try:
        del newCursor
    except:
        pass
Ejemplo n.º 30
0
def soundex(s):
    """ Encode a string using Soundex. Takes a string and returns its Soundex representation."""
    replacementString = ""
    #Added a "." here, should replace correctly now.
    replacementDict = {"A":"1", "E":"2", "H":"3", "I":"4", "O":"5", "U":"6", "W":"7", "Y":"8", ".":""} 
    
    if len(s) == 2: 
        if s[0] == s[1]:# Only affects one very specific road name type. Kind of a narrow fix.
            for keyName in replacementDict:
                if keyName == str(s[1].upper():
                    replacementString = replacementDict[keyName]
                    enc = str(str(s[0]) + replacementString).zfill(4)
                    return enc
                else:
                    pass
        else:
            pass
            
    elif len(s) == 1:
        enc = str(s[0]).zfill(4)
        return enc
    elif len(s) == 0:
        enc = str("x").zfill(4)
        return enc
    else:
        pass

    s = normalize(s)
    last = None

    enc = s[0]
    for c in s[1:]:
        if len(enc) == 4:
            break
        if charsubs[c] != last:
            enc += charsubs[c]
        last = charsubs[c]
    while len(enc) < 4:
        enc += '0'
    return enc


def numdex(s):
    """this module applies soundex to named streets, and pads the numbered streets with zeros, keeping the numbering system intact"""
    if s[0] in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
        # I don't think having a '.' here will do anything unless the road name is ".SomeName" since it
        # only checks the first character of the string.
        numerical_re = re.compile("[A-Z]|[^0-9][^0-9][^0-9][^0-9]")
        s=re.sub(numerical_re,"", s.zfill(4))
        return s.zfill(4)

    else:
        return soundex(s)


def StreetNetworkCheck(gdb):
    """removes street centerlines from the topology and creates geometric network, then checks geometric network connectivity"""
    from arcpy import ListDatasets, VerifyAndRepairGeometricNetworkConnectivity_management, RemoveFeatureClassFromTopology_management, CreateGeometricNetwork_management, FindDisconnectedFeaturesInGeometricNetwork_management
    #print topo
    fd = ListDatasets(gdb)
    print fd[0]
    geonet = fd[0]+"\Street_Network"
    #print geonet
    if Exists(geonet):
        print "Street Geometric Network Already Exists"
    else:
        RemoveFeatureClassFromTopology_management(topo, "RoadCenterline")
        CreateGeometricNetwork_management(fd, "Street_Network", "RoadCenterline SIMPLE_EDGE NO", "#", "#", "#", "#", "#")
    FindDisconnectedFeaturesInGeometricNetwork_management(fd+"/RoadCenterline", "Roads_Disconnected")
    StreetLogfile = reviewpath+"/KDOTReview/"+ntpath.basename(ng911)+".log"
    VerifyAndRepairGeometricNetworkConnectivity_management(geonet, StreetLogfile, "VERIFY_ONLY", "EXHAUSTIVE_CHECK", "0, 0, 10000000, 10000000")


def ConflateKDOTrestart(gdb, DOTRoads):
    """Conflation restart for selecting KDOT roads to conflate to the NG911 Network"""
    MakeFeatureLayer_management(DOTRoads+"/KDOT_HPMS_2012","KDOT_Roads","#","#","#")
    MakeFeatureLayer_management(checkfile+"/RoadCenterline","RoadCenterline","#","#","#")
    SelectLayerByLocation_management("KDOT_Roads","INTERSECT","RoadCenterline","60 Feet","NEW_SELECTION")
    FeatureClassToFeatureClass_conversion("KDOT_Roads",checkfile+r"/NG911","KDOT_Roads_Review","#","#","#")


def ConflateKDOT(gdb, DOTRoads):
    """detects road centerline changes and transfers the HPMS key field from the KDOT roads via ESRI conflation tools"""
    from arcpy import TransferAttributes_edit, DetectFeatureChanges_management, RubbersheetFeatures_edit, GenerateRubbersheetLinks_edit, RubbersheetFeatures_edit
    checkfile = gdb
    spatialtolerance = "20 feet"
    MakeFeatureLayer_management(DOTRoads+"/KDOT_HPMS_2012","KDOT_Roads","#","#","#")
    MakeFeatureLayer_management(checkfile+"/RoadCenterline","RoadCenterline","#","#","#")
    if Exists(checkfile+r"/NG911/KDOT_Roads_Review"):
        print "selection of KDOT roads for conflation already exists"
    else:
        SelectLayerByLocation_management("KDOT_Roads","INTERSECT","RoadCenterline","60 Feet","NEW_SELECTION")
        FeatureClassToFeatureClass_conversion("KDOT_Roads",checkfile+r"/NG911","KDOT_Roads_Review","#","#","#")
    MakeFeatureLayer_management(checkfile+"/KDOT_Roads_Review","KDOT_Roads_Review","#","#","#")
    GenerateRubbersheetLinks_edit("KDOT_Roads_Review","RoadCenterline",checkfile+r"/NG911/RoadLinks",spatialtolerance,"ROUTE_ID LRSKEY",checkfile+r"/RoadMatchTbl")
    MakeFeatureLayer_management(checkfile+"/NG911/RoadLinks","RoadLinks","#","#","#")
    MakeFeatureLayer_management(checkfile+"/NG911/RoadLinks_pnt","RoadLinks_pnt","#","#","#")
    RubbersheetFeatures_edit("KDOT_Roads_Review","RoadLinks","RoadLinks_pnt","LINEAR")
    DetectFeatureChanges_management("KDOT_Roads_Review","RoadCenterline",checkfile+r"/NG911/RoadDifference",spatialtolerance,"#",checkfile+r"/RoadDifTbl",spatialtolerance,"#")
    MakeFeatureLayer_management(checkfile+"/NG911/RoadDifference","RoadDifference","#","#","#")
    TransferAttributes_edit("KDOT_Roads_Review","RoadCenterline","YEAR_RECORD;ROUTE_ID",spatialtolerance,"#",checkfile+r"/LRS_MATCH")


def addAdminFields(lyr, Alias):
    try:
        AddIndex(lyr,"SEGID;COUNTY_L;COUNTY_R;MUNI_L;MUNI_R","RCL_INDEX","NON_UNIQUE","NON_ASCENDING")
    except:
        print "indexed"
    FieldList3=("KDOT_COUNTY_R", "KDOT_COUNTY_L","KDOT_CITY_R", "KDOT_CITY_L", 'UniqueNo' )
    for field in FieldList3:
        addField(lyr, field, "TEXT", "#", "#", "3")
    FieldList1=('KDOT_ADMO', 'KDOTPreType', 'PreCode', 'SuffCode', 'TDirCode')
    for field in FieldList1:
        addField(lyr, field, "TEXT", "#", "#", "1")
    addField(lyr, "Soundex", "TEXT", "#", "#", "5")
    addField(lyr, "RID", "TEXT", "#", "#", "26")
    addField(lyr, "KDOT_START_DATE", "DATE")
    addField(lyr, "KDOT_END_DATE", "DATE")
    addField(lyr, "SHAPE_MILES", "Double", "#", "#", "#" )
    addField(Alias, "KDOT_PREFIX", "TEXT", "#", "#", "1" )
    addField(Alias, "KDOT_CODE", "LONG" )
    addField(Alias, "KDOT_ROUTENAME", "TEXT", "#", "#", "3" )


def CalcAdminFields(lyr, Kdotdbfp):
    """Populate Admin Fields with Default or Derived values"""
    CalcField(lyr,"UniqueNo",'000',"PYTHON_9.3","#")
    CalcField(lyr,"KDOT_START_DATE","1/1/1901","PYTHON_9.3","#")
    CalcField(lyr,"KDOTPreType","!ROUTE_ID![3]","PYTHON_9.3","#") #PreType is a conflated field, consider changing this to calculate from NENA fields
    TableView(lyr, "NewPretype", "KDOTPreType is Null")
    CalcField("NewPretype","KDOTPreType","'L'","PYTHON_9.3","#")
    CalcField(lyr,"KDOT_ADMO","'X'","PYTHON_9.3","#")
    CalcField(lyr,"PreCode","0","PYTHON_9.3","#")
    CalcField(lyr,"KDOT_CITY_L","999","PYTHON_9.3","#")
    CalcField(lyr,"KDOT_CITY_R","999","PYTHON_9.3","#")
    CalcField(lyr,"TDirCode","0","PYTHON_9.3","#")
    CalcField(lyr,"SHAPE_MILES","!Shape_Length!/5280.010560021","PYTHON_9.3","#")  #There are slightly more than 5280 miles per US Survey foot
    TableView(Kdotdbfp+"\\NG911_RdDir", "NG911_RdDir")
    JoinTbl(lyr,"PRD","NG911_RdDir", "RoadDir", "KEEP_COMMON")
    CalcField(lyr,"PreCode","!NG911_RdDir.RdDirCode!","PYTHON_9.3","#")
    removeJoin(lyr)
    TableView(Kdotdbfp+"\NG911_RdTypes", "NG911_RdTypes")
    CalcField(lyr,"SuffCode","0","PYTHON_9.3","#")
    JoinTbl(lyr,"STS","NG911_RdTypes", "RoadTypes", "KEEP_COMMON")
    CalcField(lyr,"SuffCode","!NG911_RdTypes.LRS_CODE_TXT!","PYTHON_9.3","#")
    removeJoin(lyr)


def CountyCode(lyr):
    """Codify the County number for LRS (based on right side of street based on addressing direction, calculated for LEFT and RIGHT from NG911)"""
    TableView(Kdotdbfp+"\NG911_County", "NG911_County")
    JoinTbl(lyr,"COUNTY_L","NG911_County", "CountyName", "KEEP_COMMON")
    CalcField(lyr,"KDOT_COUNTY_L","!NG911_County.CountyNumber!","PYTHON_9.3","#")
    removeJoin(lyr)
    JoinTbl(lyr,"COUNTY_R","NG911_County", "CountyName", "KEEP_COMMON")
    CalcField(lyr,"KDOT_COUNTY_R","!NG911_County.CountyNumber!","PYTHON_9.3","#")
    removeJoin(lyr)


def CityCodes(lyr, Kdotdbfp):
    """Codify the City Limit\city number for LRS , calculated for LEFT and RIGHT from NG911)"""
    TableView(Kdotdbfp+"\City_Limits", "City_Limits")
    JoinTbl(lyr,"MUNI_R","City_Limits", "CITY", "KEEP_COMMON")
    CalcField(lyr,"KDOT_CITY_R","str(!City_Limits.CITY_CD!).zfill(3)","PYTHON_9.3","#")
    removeJoin(lyr)
    JoinTbl(lyr,"MUNI_L","City_Limits", "CITY", "KEEP_COMMON")
    CalcField(lyr,"KDOT_CITY_L","str(!City_Limits.CITY_CD!).zfill(3)","PYTHON_9.3","#")
    removeJoin(lyr)
    TableView(lyr, "CityRoads", "KDOT_CITY_R = KDOT_CITY_L AND KDOT_CITY_R not like '999'")
    CalcField("CityRoads","KDOT_ADMO","'W'","PYTHON_9.3","#")


def RoadinName1(lyr):
    """This module corrects the road names in the soundex code where the road is named like Road A or Road 12 """
    TableView(lyr,"ROAD_NAME","RD LIKE 'ROAD %'")
    CalcField("ROAD_NAME","Soundex",""""R"+!RD![5:].zfill(3)""","PYTHON_9.3","#")

    TableView(lyr,"RD_NAME","RD LIKE 'RD %'")
    CalcField(lyr,"Soundex","""("R"+!RD![1:5]).zfill(3)""","PYTHON_9.3","#")


def RoadinName(roadFeatures, nameExclusions):
    """This module corrects the road names in the soundex code where the road is named like Road A or Road 12 """
    fieldList = ['OBJECTID', 'RD', 'Soundex']
    listMatchString = re.compile(r'^WEST', re.IGNORECASE)
    roadNameString = ''
    roadPreSoundexString = ''
    roadSoundexString = ''
    testMatch = None
    testMatch1 = None
    testMatch2 = None

    # Get the data from the geodatabase so that it can be used in the next part of the function.
    cursor = daSearchCursor(roadFeatures, fieldList)  # @UndefinedVariable
    for row in cursor:
        listRow = list(row)
        holderList.append(listRow)

    # Clean up
    if cursor:
        del cursor
    else:
        pass
    if row:
        del row
    else:
        pass

    # Perform some regex on the strings to produce a new soundex in certain cases.
    for excludedText in nameExclusions:
        excludedText = str(excludedText)
        excludedText = excludedText.upper()
        listMatchString = re.compile(r'^{0}\s'.format(re.escape(excludedText)), re.IGNORECASE)

        # Matches 1 or 2 alpha characters at the start of a string, ignoring case.
        singleOrDoubleAlphaMatchString = re.compile(r'^[a-z]$|^[a-z][a-z]$', re.IGNORECASE)
        # Matches 1 to 4 digits at the start of a string, probably no reason to ignore case in the check.
        singleToQuadNumberMatchString = re.compile(r'^[0-9]$|^[0-9][0-9]$|^[0-9][0-9][0-9]$|^[0-9][0-9][0-9][0-9]$')

        for heldRow in holderList:
            roadNameString = str(heldRow[1])
            roadNameString = roadNameString.upper()
            testMatch = listMatchString.search(roadNameString)
            if testMatch != None:
                roadPreSoundexString = roadNameString[testMatch.end():]
                roadPreSoundexString = roadPreSoundexString.replace(" ", "")

                # Do subbing for #ST, #ND, #RD, #TH etc...
                for numberEnding in ordinalNumberEndings:
                    nonsensitiveReplace = re.compile(r'[0-9]{0}'.format(re.escape(numberEnding), re.IGNORECASE))
                    replaceMatch = nonsensitiveReplace.search(roadNameString)
                    if replaceMatch != None:
                        roadPreSoundexString = re.sub(replaceMatch.group(0), replaceMatch.group(0)[0:1], roadPreSoundexString)
                    else:
                        pass
                
                # Test for the following conditions:
                # A, AA as in Road A, RD AA
                testMatch1 = None
                testMatch1 = singleOrDoubleAlphaMatchString.search(roadPreSoundexString)
                # Test for the following conditions:
                # 1, 10, 100, 1000 as in Road 1, RD 10, Road 100, CR1000
                testMatch2 = None
                testMatch2 = singleToQuadNumberMatchString.search(roadPreSoundexString)
                if testMatch1 != None: # Road A, Road BB, or similar.
                    roadPreSoundexString = roadPreSoundexString[testMatch1.start():testMatch1.end()]
                    if len(roadPreSoundexString) > 2:
                        pass
                    elif len(roadPreSoundexString) == 2:
                        roadSoundexString = "0" + roadPreSoundexString
                        # Adds the first letter from the excluded text to the start of the Soundex string.
                        roadSoundexString = excludedText[0:1] + roadSoundexString
                    elif len(roadPreSoundexString) == 1:
                        roadSoundexString = "00" + roadPreSoundexString
                        roadSoundexString = excludedText[0:1] + roadSoundexString
                    else:
                        pass
                
                elif(testMatch2 != None):
                    roadPreSoundexString = roadPreSoundexString[testMatch2.start():testMatch2.end()]
                    if len(roadPreSoundexString) > 4:
                        pass
                    elif len(roadPreSoundexString) == 4:
                        # Slice the string to include only the first 3 characters.
                        roadSoundexString = roadPreSoundexString[:4]
                        # Add the first letter from the excluded text to the start of the Soundex string.
                        roadSoundexString = excludedText[0:1] + roadSoundexString
                    elif len(roadPreSoundexString) == 3:
                        roadSoundexString = roadPreSoundexString
                        roadSoundexString = excludedText[0:1] + roadSoundexString
                    elif len(roadPreSoundexString) == 2:
                        roadSoundexString = "0" + roadPreSoundexString
                        roadSoundexString = excludedText[0:1] + roadSoundexString
                    elif len(roadPreSoundexString) == 1:
                        roadSoundexString = "00" + roadPreSoundexString
                        roadSoundexString = excludedText[0:1] + roadSoundexString
                    else:
                        pass
                
                # One of the excluded texts was found at the start of the name, but it was not followed by
                # A, AA, 1, 20, 340, 5670, etc...
                # Instead something like "Road Hitch" or "RD Empire"
                # Do soundex normally, but replace the first character with the first character from the
                # excluded text.
                else:
                    roadSoundexString = soundex(roadPreSoundexString)
                    # Slice the roadSoundexString to remove the first character, but keep the rest.
                    roadSoundexString = roadSoundexString[1:]
                    # Add the first letter from the excluded text to the start of the Soundex string.
                    roadSoundexString = excludedText[0:1] + roadSoundexString

                # Assign the new road soundex string to the held row's third slot, heldRow[2],
                # to be used in an update cursor to update the data in the geodatabase.
                heldRow[2] = roadSoundexString
            else:
                pass

    # Start an edit session for this workspace because the centerline
    # feature class participates in a topology.
    editSession = daEditor(gdb)
    editSession.startEditing(False, False)
    editSession.startOperation()

    cursor = daUpdateCursor(roadFeatures, fieldList)  # @UndefinedVariable
    for row in cursor:
        for heldRow in holderList:
            if row[0] == heldRow[0]:
                cursor.updateRow(heldRow)
            else:
                pass

    # Clean up
    if cursor:
        del cursor
    else:
        pass
    if row:
        del row
    else:
        pass

    editSession.stopOperation()
    editSession.stopEditing(True)


def RouteCalc(lyr, soundexNameExclusions):
    """calculate what should be a nearly unique LRS Route key based on the decoding and street name soundex/numdex function"""
    #CalcField(lyr,"Soundex","numdex(!RD!)","PYTHON_9.3","#")
    RoadinName(lyr, soundexNameExclusions)
    CalcField(lyr, "RID", "str(!KDOT_COUNTY_R!)+str(!KDOT_COUNTY_L!)+str(!KDOT_CITY_R!)+str(!KDOT_CITY_L!)+str(!PreCode!) + !Soundex! + str(!SuffCode!)+str(!UniqueNo!)+str(!TDirCode!)","PYTHON_9.3","#")

# Instead of calling numdex here, rewrite and incorporate numdex and soundex functionality into the RoadinName function.

def AliasCalc(Alias, DOTRoads):
    CalcField(Alias, "KDOT_PREFIX", "!LABEL![0]","PYTHON_9.3","#")
    CalcField(Alias,"KDOT_ROUTENAME","""!A_RD![1:].replace("S","").zfill(3)""","PYTHON_9.3","#")
    TableView(DOTRoads+"\KDOT_RoutePre", "KDOT_RoutePre")
    JoinTbl("RoadAlias", "KDOT_PREFIX", "KDOT_RoutePre", "LRSPrefix", "KEEP_COMMON")
    CalcField("RoadAlias","RoadAlias.KDOT_CODE","!KDOT_RoutePre.PreCode!","PYTHON_9.3","#")
    removeJoin("RoadAlias")

    
def HighwayCalc(lyr, gdb, Alias):
    """Pull out State Highways to preserve KDOT LRS Key (CANSYS FORMAT - non directional CRAD)"""
    if Exists(gdb+"\RoadAlias_Sort"):
        Delete(gdb+"\RoadAlias_Sort")
    else:
        pass
    Sort_management(Alias,gdb+"\RoadAlias_Sort","KDOT_CODE ASCENDING;KDOT_ROUTENAME ASCENDING","UR")

    #Heiarchy did not sort or calc correctly for Cheyenne County, US36 over K161 1st
    #Sot and join doesnt accomplish primary route key designsation... but calculaing over hte heirarchy should...
    #Remember to check the primary route heirarchy calculates correctly where US rides US and I rides I
    Heriarchy = ["K", "U", "I"]
    for routeClass in Heriarchy:
        rideselect =  "KDOT_PREFIX LIKE '"+routeClass+"%'"
        print rideselect, routeClass
        TableView(gdb+"\RoadAlias_Sort", "RoadAlias_Sort", rideselect)
        JoinTbl(lyr,"SEGID","RoadAlias_Sort", "SEGID", "KEEP_COMMON")
        CalcField(lyr,lyr+".KDOTPreType","!RoadAlias_Sort.KDOT_PREFIX!","PYTHON_9.3","#")
        CalcField(lyr,lyr+".Soundex","!RoadAlias_Sort.KDOT_PREFIX!+!RoadAlias_Sort.KDOT_ROUTENAME!","PYTHON_9.3","#")
        CalcField(lyr,"KDOT_ADMO","'S'","PYTHON_9.3","#")
        CalcField(lyr,"PreCode","0","PYTHON_9.3","#")
        removeJoin(lyr)
    CalcField(lyr, "RID", "str(!KDOT_COUNTY_R!)+str(!KDOT_COUNTY_L!)+str(!KDOT_CITY_R!)+str(!KDOT_CITY_L!)+str(!PreCode!) + !Soundex! + str(!SuffCode!)+str(!UniqueNo!)+str(!TDirCode!)","PYTHON_9.3","#")
    CalcField(lyr, "LRSKEY", "str(!RID!)", "PYTHON_9.3","#")

    
def ScratchCalcs():
    CalcField("RoadCenterline","RoadCenterline.Soundex","""!RoadAlias.A_RD![0]  +  !RoadAlias.A_RD![1:].replace("S","").zfill(3)""","PYTHON_9.3","#")
    CalcField(in_table="RoadCenterline",field="RoadCenterline.KDOTPreType",expression="!RoadAlias.A_RD![0]  ",expression_type="PYTHON_9.3",code_block="#")
    CalcField(in_table="RoadCenterline",field="RoadCenterline.PreCode",expression="'0'",expression_type="PYTHON_9.3",code_block="#")
    CalcField(in_table="RoadCenterline",field="RoadCenterline.KDOT_ADMO",expression="'S'",expression_type="PYTHON_9.3",code_block="#")

    
def LRS_Tester():
    """makes the LRS route layer and dissolves the NG911 fields to LRS event tables"""
    # Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script
    # The following inputs are layers or table views: "RoadCenterline"
    from arcpy import Dissolve_management as dissolve
    CalcField(lyr, "LRSKEY", "str(!KDOT_COUNTY_R!)+str(!KDOT_COUNTY_L!)+str(!KDOT_CITY_R!)+str(!KDOT_CITY_L!)+str(!PreCode!) + !Soundex! + str(!SuffCode!)+str(!UniqueNo!)+str(!TDirCode!)","PYTHON_9.3","#")
    CalcField(lyr, "RID", "str(!KDOT_COUNTY_R!)+str(!KDOT_COUNTY_L!)+str(!KDOT_CITY_R!)+str(!KDOT_CITY_L!)+str(!PreCode!) + !Soundex! + str(!SuffCode!)+str(!UniqueNo!)+str(!TDirCode!)","PYTHON_9.3","#")


    env.overwriteOutput = 1
    dissolve(lyr,gdb+"/NG911/RCLD1","LRSKEY","SEGID COUNT;L_F_ADD MIN;L_T_ADD MAX;L_F_ADD RANGE;L_T_ADD RANGE;SHAPE_MILES SUM","MULTI_PART","DISSOLVE_LINES")
    dissolve(lyr,gdb+"/NG911/RCLD2","LRSKEY","SEGID COUNT;L_F_ADD MIN;L_T_ADD MAX;L_F_ADD RANGE;L_T_ADD RANGE;SHAPE_MILES SUM","MULTI_PART","UNSPLIT_LINES")

    #MakeRouteLayer_na()
    pass

    
uniqueIdInFields = ["OBJECTID", "COUNTY_L", "COUNTY_R", "STATE_L", "STATE_R", "L_F_ADD", "L_T_ADD", "R_F_ADD", "R_T_ADD", "UniqueNo", "LRSKEY", "SHAPE_MILES"]
uniqueIdOutFields = ["OBJECTID", "UniqueNo", "LRSKEY"]


def createUniqueIdentifier(gdb, lyr, inFieldNamesList, outFieldNamesList):
    '''filters through records and calculates an incremental Unique Identifier for routes that are not border routes, to handle Y's, eyebrows, and splits that would cause complex routes'''
    workspaceLocation = gdb
    #MakeFeatureLayer_management(lyr,"RCL_Particles",where_clause="COUNTY_L = COUNTY_R AND STATE_L = STATE_R AND ( L_F_ADD =0 OR L_T_ADD =0 OR R_F_ADD =0 OR R_T_ADD =0)")
    featureClassName = lyr
    from arcpy.da import SearchCursor as daSearchCursor, UpdateCursor as daUpdateCursor, Editor as daEditor
    alphabetListForConversion = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    newCursor = daSearchCursor(featureClassName, inFieldNamesList)
    searchList = list()
    for searchRow in newCursor:
        searchList.append(list(searchRow)) # Transforms the row tuple into a list so it can be edited.

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

    matchCount = 0
    matchList = list()

    for testRow in searchList:
        if (testRow[1] == testRow[2] and testRow[3] == testRow[4] and (str(testRow[5]) == "0" or str(testRow[6]) == "0" or str(testRow[7]) == "0" or str(testRow[8]) == "0")):
            matchCount += 1
            matchList.append(testRow)

    matchedRowDictionary = dict()

    for matchedRow in matchList:
        matchedRowContainer = list()
        # If the key already exists, assign the previous list of lists
        # to the list container, then append the new list
        # before updating the new value to that key in the dictionary.
        if matchedRow[10] in matchedRowDictionary:
            matchedRowContainer = matchedRowDictionary[matchedRow[10]]
            matchedRowContainer.append(matchedRow)
            matchedRowDictionary[matchedRow[10]] = matchedRowContainer
        # Otherwise, the key needs to be created
        # with the value, the list container, having only
        # one list contained within it for now.
        else:
            matchedRowContainer.append(matchedRow)
            matchedRowDictionary[matchedRow[10]] = matchedRowContainer

    for LRSKey in matchedRowDictionary:
        outRowContainer = matchedRowDictionary[LRSKey]
        # Sort based on length
        outRowContainer = sorted(outRowContainer, key = lambda sortingRow: sortingRow[11])
        countVariable = 0 # Start at 0 for unique values
        LRSVariable = ""
        for outRowIndex, outRow in enumerate(outRowContainer):
            # Is this the first list/row in the key's list container?
            # If so, then set the Resolution_Order to 0
            if outRowIndex == 0:
                outRow[9] = 0
            else:
                countVariable += 1
                if countVariable in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
                    outRow[9] = countVariable
                elif countVariable >= 10 and countVariable <= 34:
                    outRow[9] = alphabetListForConversion[countVariable - 10] # Converts countVariable to an alpha character, without the letter "O".
                else:
                    print "The count Variable is above 34. Ran out of numbers and letters to use as unique values."

            LRSVariable = outRow[10]
            LRSVariableShortened = str(LRSVariable[:-1]) # Returns the LRSVariable without the last character.
            LRSVariable = LRSVariableShortened + str(outRow[9])
            outRow[10] = LRSVariable

            outRowString = ""

            for outRowElement in outRow:
                outRowString = outRowString + str(outRowElement) + " "

            print outRowString

            outRowContainer[outRowIndex] = outRow

        matchedRowDictionary[LRSKey] = outRowContainer

    newEditingSession = daEditor(workspaceLocation)
    newEditingSession.startEditing()
    newEditingSession.startOperation()

    newCursor = daUpdateCursor(featureClassName, outFieldNamesList)  # @UndefinedVariable
    for existingRow in newCursor:
        formattedOutRow = list()
        if existingRow[2] in matchedRowDictionary.keys():
            outRowContainer = matchedRowDictionary[existingRow[2]]
            for outRow in outRowContainer:
                if existingRow[0] == outRow[0]: # Test for matching OBJECTID fields.
                    formattedOutRow.append(outRow[0])
                    formattedOutRow.append(outRow[9])
                    formattedOutRow.append(outRow[10])
                    newCursor.updateRow(formattedOutRow)
                else:
                    pass

        else:
            pass

    newEditingSession.stopOperation()
    newEditingSession.stopEditing(True)

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


#ConflateKDOT(gdb, DOTRoads)
#addAdminFields(lyr, Alias)
#CalcAdminFields(lyr, Kdotdbfp)
#CountyCode(lyr)
#CityCodes(lyr, Kdotdbfp)
RouteCalc(lyr, soundexNameExclusions)
#AliasCalc(Alias, DOTRoads)
#HighwayCalc(lyr, gdb, Alias)
#StreetNetworkCheck(gdb)
#createUniqueIdentifier(gdb, lyr, uniqueIdInFields, uniqueIdOutFields)
#LRS_Tester()
def removeSmallRoads():

    # Going to have to build a list of OIDs for roads
    # with a Shape length less than or equal to 1500.
    # Not going to have the SQL information to do a
    # selection based on a clause.

    # Could also add a field and then calculate the
    # length into it prior to running this selection.

    # Need to make a search cursor that gets the ObjectID and ShapeLength
    # for each road.

    # Then, need to add the ObjectID for roads with ShapeLength less than
    # 1500 to a list, then build SQL queries dynamically to select
    # and add features from that list, until the list is exhausted
    # and all features have been selected.

    print "Removing the small roads from the data."

    #CopyFeatures_management(countyRoadsFeature, countyRoadsFeaturePrereduction_Q)

    inMemoryRoadsLayer = 'inMemoryRoadsLayerFC'

    MakeFeatureLayer_management(countyRoadsFeature, inMemoryRoadsLayer)

    inMemRoadsFields = ListFields(inMemoryRoadsLayer)

    for inMemRoadField in inMemRoadsFields:
        print str(inMemRoadField.name)

    smallRoadsSCFields = ['ID2', 'Shape@Length']

    smallRoadsSearchCursor = daSearchCursor(inMemoryRoadsLayer,
                                            smallRoadsSCFields)

    roadIDsToRemove = list()
    '''
    for smallRoadRow in smallRoadsSearchCursor:
        if int(str(smallRoadRow[0])) % 500 == 0:
            print str(smallRoadRow[0])
        else:
            pass
        
    raise("Stop error.")
    '''

    for smallRoadRow in smallRoadsSearchCursor:
        if smallRoadRow[1] <= 1500:
            roadIDsToRemove.append(smallRoadRow[0])
        else:
            pass

    roadRemovalCounter = 0

    roadsReductionWhereClause = """ "ID2" IN ("""

    for roadID in roadIDsToRemove:
        if roadRemovalCounter <= 998:
            roadsReductionWhereClause = roadsReductionWhereClause + str(
                roadID) + """, """
            roadRemovalCounter += 1
        else:
            # Remove the trailing ", " and add a closing parenthesis.
            roadsReductionWhereClause = roadsReductionWhereClause[:-2] + """) """
            SelectLayerByAttribute_management(inMemoryRoadsLayer,
                                              "ADD_TO_SELECTION",
                                              roadsReductionWhereClause)

            # Debug only
            print "Selecting..."
            selectedRoadsResult = GetCount_management(inMemoryRoadsLayer)
            selectedRoadsCount = int(selectedRoadsResult.getOutput(0))
            print "Number of roads selected: " + str(selectedRoadsCount)

            roadRemovalCounter = 0
            roadsReductionWhereClause = """ "ID2" IN ("""
            roadsReductionWhereClause = roadsReductionWhereClause + str(
                roadID) + """, """

    # Remove the trailing ", " and add a closing parenthesis.
    roadsReductionWhereClause = roadsReductionWhereClause[:-2] + """) """
    SelectLayerByAttribute_management(inMemoryRoadsLayer, "ADD_TO_SELECTION",
                                      roadsReductionWhereClause)

    # Debug only
    print "Selecting..."
    selectedRoadsResult = GetCount_management(inMemoryRoadsLayer)
    selectedRoadsCount = int(selectedRoadsResult.getOutput(0))
    print "Number of roads selected: " + str(selectedRoadsCount)

    selectedRoadsResult = GetCount_management(inMemoryRoadsLayer)

    selectedRoadsCount = int(selectedRoadsResult.getOutput(0))

    if selectedRoadsCount >= 1:
        DeleteFeatures_management(inMemoryRoadsLayer)
    else:
        pass
def duplicateNameRemoval():
    print "Starting duplicate name removal."
    newCursor = daSearchCursor(countyRoadNameRosette, countyRoadNameRosetteFieldsObjShape)
    
    countyNamePointList = list()
    
    for eachPoint in newCursor:
        countyNamePointList.append(eachPoint)
        
    if "newCursor" in locals():
        del newCursor
    else:
        pass
    
    pointDeleteList = list()
    
    for pointItem in countyNamePointList:
        for pointToCheck in countyNamePointList:
            # If the points share a road name, and a county number, but not the same ObjectID...
            if pointItem[0] not in pointDeleteList:
                if pointItem[3] == pointToCheck[3] and str(pointItem[2]).upper() == str(pointToCheck[2]).upper() and (not pointItem[0] == pointToCheck[0]):
                    # Use the distance formula to check to see if these points are within a
                    # certain distance from one another.
                    # If so, add the pointToCheck to the pointDeleteList.
                    distance = 0
                    point1 = pointItem[1]
                    point2 = pointToCheck[1]
                    
                    
                    distance = calcPointDistance(point1, point2)
                    
                    # Added "and pointToCheck not in pointDeleteList"
                    # to prevent two points from both adding a 3rd point to the list.
                    # Also, the distance looks enormous, but it's only about 1500 meters in Lambert_Conformal_Conic_2SP.
                    # @ 450,000 = maxDistance. -- Check smaller values before implementing, however...
                    # as going from 15000 to 450000 adds a long time to this function's execution.
                    # maybe remove the equality on the upper bound, and change the lower bound
                    # to -1 or something like that.
                    
                    # Change this to add just the objectid to the pointDeleteList
                    # instead of the whole point row to increase the speed
                    # of the check when the list grows to a decent size.
                    # Distance of 10000 seems to give good results.
                    if distance >= 0 and distance < 10000 and pointToCheck[0] not in pointDeleteList:
                        pointDeleteList.append(pointToCheck[0])
                    else:
                        pass
                else:
                    pass
            else:
                pass
    
    newCursor = daUpdateCursor(countyRoadNameRosette, countyRoadNameRosetteFieldsObjShape)
    
    for updateableRow in newCursor:
        for pointToDeleteOID in pointDeleteList:
            if updateableRow[0] == pointToDeleteOID:
                print "Selected a point for " + str(updateableRow[2]) + " in " + str(updateableRow[3]) + " county to delete."
                newCursor.deleteRow()
                print "Point deleted."
            else:
                pass
        #updateCursor
        #delete pointToDelete from countyRoadNameRosette.
        #print a message saying that the point was deleted.
    
    if "newCursor" in locals():
        del newCursor
    else:
        pass
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
Ejemplo n.º 34
0
def transferFeatures():
    env.workspace = in_memory
    featuresToTransfer = list()
    try:
        # Create an in_memory feature class which to hold the features from
        # the Oracle table.
        FeatureClassToFeatureClass_conversion(kanRoadRCRSRoads, "in_memory",
                                              "RCRS")

        # Then, define a projection on it, since the original Oracle table
        # is lacking the proper information.
        DefineProjection_management("in_memory\RCRS", lambertCC)

        #truncating CDRS segments in KanDrive Spatial
        print str(datetime.datetime.now()
                  ) + " truncating RCRS segments in KanDrive Spatial."
        TruncateTable_management(kanDriveSpatialConditions)

        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to both of the
        # tables and give it the same name in both.
        ###############################################################################################################

        # searchCursorFields go to r"in_memory\RCRS". (Input table)(Indirect)
        descObject = Describe(r"in_memory\RCRS")
        searchCursorFields = [
            field.name for field in descObject.fields
            if field.name != descObject.OIDFieldName and field.name != "Shape"
            and field.name != "ID1"
        ]
        searchCursorFields.append('SHAPE@')

        # Make the insertCursor use the same fields as the searchCursor.
        insertCursorFields = searchCursorFields

        print "OIDFieldname = " + descObject.OIDFieldName

        print "fieldNames to be used in the searchCursor (and insertCursor):"
        for fieldName in searchCursorFields:
            print fieldName

        RCRS_SearchCursor = daSearchCursor(r"in_memory\RCRS",
                                           searchCursorFields)

        for RCRS_CursorItem in RCRS_SearchCursor:
            featureItem = list(RCRS_CursorItem)
            featuresToTransfer.append(featureItem)

        RCRS_InsertCursor = daInsertCursor(kanDriveSpatialConditions,
                                           insertCursorFields)

        for RCRS_Feature in featuresToTransfer:
            insertOID = RCRS_InsertCursor.insertRow(RCRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)

    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement

        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging('KanDrive_Spatial_Conditions_Update',
                            'kandrive_spatial.DBO.Conditions', scriptFailure,
                            startTime, endTime, errorItem.args[0],
                            pythonLogTable)

        try:
            del errorItem
        except:
            pass

        # Reraise the error to stop execution and prevent a success message
        # from being inserted into the table.
        raise

    finally:
        try:
            del RCRS_SearchCursor
        except:
            pass
        try:
            del RCRS_InsertCursor
        except:
            pass
Ejemplo n.º 35
0
def RoadinName(roadFeatures, nameExclusions):
    """This module corrects the road names in the soundex code where the road is named like Road A or Road 12 """
    # Need to add logic to remove the ST from roads like 3RD ST and make sure that this translates to 0003
    # and not 003.
    fieldList = ['OBJECTID', 'RD', 'Soundex']
    #Placeholder. Recompiled in nameExclusions for loop.
    listMatchString = re.compile(r'^WEST', re.IGNORECASE)
    roadNameString = ''
    roadPreSoundexString = ''
    roadSoundexString = ''
    holderList = list()

    testMatch0 = None
    testMatch1 = None
    testMatch2 = None
    testMatch3 = None

    # Get the data from the geodatabase so that it can be used in the next part of the function.
    cursor = daSearchCursor(roadFeatures, fieldList)  # @UndefinedVariable
    for row in cursor:
        listRow = list(row)
        holderList.append(listRow)

    # Clean up
    if "cursor" in locals():
        del cursor
    else:
        pass
    if "row" in locals():
        del row
    else:
        pass

    # Matches any group of 3 alpha characters in the string, ignoring case.
    tripleAlphaMatchString = re.compile(r'[A-Z][A-Z][A-Z]', re.IGNORECASE)
    # Matches 1 or 2 alpha characters at the start of a string, ignoring case.
    singleOrDoubleAlphaMatchString = re.compile(r'^[A-Z]$|^[A-Z][A-Z]$', re.IGNORECASE)
    # Matches 1 to 4 digits at the start of a string, probably no reason to ignore case in the check.
    singleToQuadNumberMatchString = re.compile(r'^[0-9]$|^[0-9][0-9]$|^[0-9][0-9][0-9]$|^[0-9][0-9][0-9][0-9]$')
    anyNumberMatchString = re.compile(r'[0-9]', re.IGNORECASE)

    # For roads that don't match a name exclusion:
    singleOrDoubleNumberThenAlphaMatchString = re.compile(r'^[0-9][0-9][A-Z]$|^[0-9][A-Z]$', re.IGNORECASE)
    # For roads that don't match a name exclusion and should be normally Numdexed.
    firstCharacterNumberString = re.compile(r'^[0-9]')

    ## Significant structure change here 2014-11-05.
    ## Watch for possible bugs.
    ##
    ## Added Numdex logic to this part, which
    ## caused some issues.
    ##
    ## Flattened the loops out here so that it only
    ## does a run through the
    ## <for heldRow in holderList>
    ## loop once instead of doing it once per
    ## entry in the nameExclusions list via
    ## <for excludedText in nameExclusions>
    ##
    ## Runs faster now. After changing the regex string
    ## to be dynamically generated prior to compilation
    ## and using \b{0}\b as part of the pattern,
    ## errors *seem* to be gone.

    stringToCompile = ""

    # Perform some regex on the strings to produce a new soundex in certain cases.
    for i, excludedText in enumerate(nameExclusions): #shift left start
        excludedText = str(excludedText)
        excludedText = excludedText.upper()
        #listMatchString = re.compile(r'^{0}\s'.format(re.escape(excludedText)), re.IGNORECASE) ## Old version, pre-dynamic generation.
        if i == 0:
            stringToCompile = r'^\b{0}\b\ '.format(re.escape(excludedText))
        else:
            stringToCompile = stringToCompile + r'|^\b{0}\b\ '.format(re.escape(excludedText))
        print i
        listMatchString = re.compile(stringToCompile, re.IGNORECASE)

    print "stringToCompile = " + str(stringToCompile)

    for heldRow in holderList:
        roadNameString = ''
        roadPreSoundexString = ''
        roadSoundexString = ''

        roadNameString = str(heldRow[1])
        roadNameString = roadNameString.upper()
        roadNameString = roadNameString.replace(".", "")

        exclusionMatch = listMatchString.search(roadNameString)
        if exclusionMatch != None: # Testing for excluded Road Names such as "Road" and "CR" in "Road 25" and "CR 2500".
            # Get the characters from the end of the testMatch to the end of the string.
            # Should return a string that starts with a space.

            roadPreSoundexString = roadNameString[exclusionMatch.end():]

            # Replace with a search for " " by group in regex.
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")
            # then loop through the groups to replace with "" so that any number
            # of spaces can be removed.

            print "roadNameString = " + str(roadNameString)
            print "roadPreSoundexString = " + str(roadPreSoundexString)

            # Do subbing for #ST, #ND, #RD, #TH etc...
            for numberEnding in ordinalNumberEndings:
                nonsensitiveReplace = re.compile(r'[0-9]{0}'.format(re.escape(numberEnding), re.IGNORECASE))
                replaceMatch = nonsensitiveReplace.search(roadNameString)
                if replaceMatch != None:
                    roadPreSoundexString = re.sub(replaceMatch.group(0), "", roadPreSoundexString)
                else:
                    pass

            # Replace with regex string that matches spaces as groups, then loop through groups to replace.
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")
            roadPreSoundexString = roadPreSoundexString.replace(" ", "")

            testMatch0 = None
            testMatch0 = tripleAlphaMatchString.search(roadPreSoundexString)
            testMatch1 = None
            testMatch1 = singleOrDoubleAlphaMatchString.search(roadPreSoundexString)
            testMatch2 = None
            testMatch2 = singleToQuadNumberMatchString.search(roadPreSoundexString)
            testMatch3 = None
            testMatch3 = anyNumberMatchString.search(roadPreSoundexString)

            if testMatch0 != None:
                roadSoundexString = soundex(roadPreSoundexString)
                # Slice the roadSoundexString to remove the first character, but keep the rest.
                if len(roadSoundexString) >= 4:
                    roadSoundexString = roadSoundexString[1:4]
                    # The next line looks complicated, but exclusionMatch.group(0)[0:1]
                    # is actually just getting the first letter of the first matched pattern.
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                elif len(roadSoundexString) == 3:
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                elif len(roadSoundexString) == 2 or len(roadSoundexString) == 1:
                    roadSoundexString = roadSoundexString.zfill(3)
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                else:
                    pass

                heldRow[2] = roadSoundexString

            elif testMatch1 != None: # Road A, Road BB, or similar.
                roadPreSoundexString = roadPreSoundexString[testMatch1.start():testMatch1.end()]
                if len(roadPreSoundexString) > 2:
                    pass
                elif len(roadPreSoundexString) == 2:
                    roadSoundexString = "0" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 1:
                    roadSoundexString = "00" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                else:
                    pass

            elif testMatch2 != None:
                roadPreSoundexString = roadPreSoundexString[testMatch2.start():testMatch2.end()]
                if len(roadPreSoundexString) > 4:
                    pass
                elif len(roadPreSoundexString) == 4:
                    # Slice the string to include only the first 3 characters, as slice end is non-inclusive.
                    roadSoundexString = roadPreSoundexString[:4]
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 3:
                    roadSoundexString = roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 2:
                    roadSoundexString = "0" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                elif len(roadPreSoundexString) == 1:
                    roadSoundexString = "00" + roadPreSoundexString
                    roadSoundexString = exclusionMatch.group(0)[0:1] + roadSoundexString
                    heldRow[2] = roadSoundexString
                else:
                    pass
            else:
                pass

        else:
            roadNameString = heldRow[1]
            testMatch4 = None
            testMatch4 = singleOrDoubleNumberThenAlphaMatchString.search(roadNameString)
            testMatch5 = None
            testMatch5 = firstCharacterNumberString.search(roadNameString)

            # Numdex with one or two numbers, then alpha.
            if testMatch4 != None:
                roadPreSoundexString = roadNameString[testMatch4.start():]
                roadSoundexString = roadPreSoundexString.zfill(4)
                heldRow[2] = roadSoundexString
            # Normal Numdex if there were not one or two numbers, then alpha, but the string starts with a number.
            elif testMatch5 != None:
                numerical_re = re.compile("[A-Z]|[^0-9][^0-9][^0-9][^0-9]")

                roadPreSoundexString = roadNameString.replace(" ", "")
                roadSoundexString = re.sub(numerical_re,"", roadPreSoundexString.zfill(4))

                if len(roadSoundexString) > 4:
                    roadSoundexString = roadSoundexString[:5]
                else:
                    pass

                roadSoundexString = roadSoundexString.zfill(4)

                heldRow[2] = roadSoundexString

            else: # Check for AA, BB, EE, etc without an excluded name in front of it
                if len(roadNameString) == 2:
                    if roadNameString[0] == roadNameString[1]:
                        roadPreSoundexString = roadNameString
                        roadSoundexString = roadPreSoundexString.zfill(4)
                else: # Normal Soundex
                    roadPreSoundexString = roadNameString
                    roadSoundexString = soundex(roadPreSoundexString)

                heldRow[2] = roadSoundexString # shift left end


    try:
        # Start an edit session for this workspace because the centerline
        # feature class participates in a topology.
        editSession = daEditor(gdb)
        editSession.startEditing(False, False)
        editSession.startOperation()

        print "Editing started."

        cursor = daUpdateCursor(roadFeatures, fieldList)  # @UndefinedVariable
        for row in cursor:
            for heldRow in holderList: # N^2 looping, try not to place print statements inside this block.
                if str(row[0]) == str(heldRow[0]):
                    cursor.updateRow(heldRow)
                else:
                    pass

        editSession.stopOperation()
        editSession.stopEditing(True)

        print "Editing complete."

    except Exception as e:
        print "Failed to update the Soundex values."
        print e.message
        print GetMessages(2)

    finally:
        # Clean up
        if "cursor" in locals():
            del cursor
        else:
            pass
        if "row" in locals():
            del row
        else:
            pass
def transferFeatures():
    env.workspace = in_memory
    featuresToTransfer = list()
    try:
        print str(
            datetime.datetime.now()) + ' copying the oracle table to memory'

        # Create an in_memory feature class which to hold the features from
        # the Oracle table.
        FeatureClassToFeatureClass_conversion(
            sdeCDRS, "in_memory", "CDRS", "#",
            "ALERT_STATUS <>  3 AND AlertType = 'Road Incident'")

        # Then, define a projection on it, since the original Oracle table
        # is lacking the proper information.
        DefineProjection_management("in_memory\CDRS", lambertCC)

        #truncating CDRS segments in KanDrive Spatial
        print str(datetime.datetime.now()
                  ) + " truncating Incident segments in KanDrive Spatial."
        TruncateTable_management(kanDriveSpatialIncidents)

        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to both of the
        # tables and give it the same name in both.
        # If you need to add another field to just one, the list comprehension will automatically
        # exclude it.
        #
        # If you need to add another field to transfer between the two and it has to be named
        # different things in each table, you will need to append the matching name to the searchCursorFields list
        # and insertCursorFields list are generated.
        #
        # I.e. if you add a field named "snowFlakeCount" to the CDRS_ALERT_ROUTE table and a field named
        # "snowFlakeCounter" to the kandrive_spatial.DBO.Incidents table, you would need to append
        # "snowFlakeCount" to the searchCursorFields and "snowFlakeCounter" to the insertCursorFields for
        # them to match up and transfer properly. -- If possible, avoid this by naming them both the same thing.
        #
        # If you're having to do several appends, it may be best to just write out all of the field names for
        # each list in the order that you would like for them to be transfered. This is how the field names
        # are listed in the Kandrive_Construction_Update.py script.
        ###############################################################################################################

        CDRS_Desc_Object = Describe(r"in_memory\CDRS")
        CDRS_Desc_Fields = [field.name for field in CDRS_Desc_Object.fields]
        Incidents_Desc_Object = Describe(kanDriveSpatialIncidents)
        Incidents_Desc_Fields = [
            field.name for field in Incidents_Desc_Object.fields
        ]

        # This Python list comprehension creates the intersection of the two *_Fields lists
        # and makes sure that the Shape field and Object ID fields are not directly
        # transfered. -- The 'SHAPE@' token indirectly transfers the geometry instead
        # and the Object ID of the target feature class is automatically calculated
        # by the insert cursor.
        searchCursorFields = [
            fieldName for fieldName in CDRS_Desc_Fields
            if fieldName in Incidents_Desc_Fields
            and fieldName != CDRS_Desc_Object.OIDFieldName and fieldName !=
            Incidents_Desc_Object.OIDFieldName and fieldName != 'Shape'
        ]

        searchCursorFields.append('SHAPE@')

        # Make the insertCursor use the same fields as the searchCursor.
        insertCursorFields = searchCursorFields

        print "OIDFieldnames: " + CDRS_Desc_Object.OIDFieldName + " & " + Incidents_Desc_Object.OIDFieldName + "."

        print "fieldNames to be used in the searchCursor (and insertCursor):"
        for fieldName in searchCursorFields:
            print fieldName

        Incidents_Where_Clause = "ALERT_TYPE_TXT = 'Road Incident'"

        CDRS_SearchCursor = daSearchCursor(r"in_memory\CDRS",
                                           searchCursorFields,
                                           Incidents_Where_Clause)

        for CDRS_CursorItem in CDRS_SearchCursor:
            featureItem = list(CDRS_CursorItem)
            featuresToTransfer.append(featureItem)

        ##Debug
        for feature in featuresToTransfer:
            print feature
        ##

        Incidents_InsertCursor = daInsertCursor(kanDriveSpatialIncidents,
                                                insertCursorFields)

        for CDRS_Feature in featuresToTransfer:
            insertOID = Incidents_InsertCursor.insertRow(CDRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)
        '''
        print "fieldNames to be used in the searchCursor:"
        for fieldName in searchCursorFields:
            print fieldName        
        
        incidents_Where_Clause = "AlertType = 'Road Incident'"
        
        Construction_SearchCursor = daSearchCursor(sdeCDRS, searchCursorFields, incidents_Where_Clause)
        
        for Construction_CursorItem in Construction_SearchCursor:
            featureItem = list(Construction_CursorItem)
            featuresToTransfer.append(featureItem)
        
        Incidents_InsertCursor = daInsertCursor(kanDriveSpatialIncidents, insertCursorFields)
        
        for Construction_Feature in featuresToTransfer:
            insertOID = Incidents_InsertCursor.insertRow(Construction_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)
    
    '''
    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement

        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging('KanDrive_Spatial_Incidents_Update',
                            'kandrive_spatial.DBO.Incidents', scriptFailure,
                            startTime, endTime, errorItem.args[0],
                            pythonLogTable)

        try:
            del errorItem
        except:
            pass

        # Reraise the error to stop execution and prevent a success message
        # from being inserted into the table.
        raise

    finally:
        try:
            del CDRS_SearchCursor
        except:
            pass
        try:
            del Incidents_InsertCursor
        except:
            pass
def TnA():
    try:
        env.workspace = stagews
        # copying oracle tables to memory
        print str(datetime.datetime.now()) + " copying oracle tables to memory"
        FeatureClassToFeatureClass_conversion(sdeCDRS, "in_memory", "Construction", "#", "ALERT_STATUS <>  3")
        MakeQueryTable_management(
            sdeCDRSWZ,
            "wz1",
            "USE_KEY_FIELDS",
            "KANROAD.CDRS_WZ_DETAIL.CDRS_WZ_DETAIL_ID",
            """KANROAD.CDRS_WZ_DETAIL.CDRS_WZ_DETAIL_ID #;KANROAD.CDRS_WZ_DETAIL.CDRS_DETOUR_TYPE_ID #;
                                KANROAD.CDRS_WZ_DETAIL.WORK_ZONE_DESC #;KANROAD.CDRS_WZ_DETAIL.WORK_ZONE_SPEED_RESTRIC #;
                                KANROAD.CDRS_WZ_DETAIL.DETOUR_TYPE_TXT #;KANROAD.CDRS_WZ_DETAIL.DETOUR_SPEED_RESTRIC #;
                                KANROAD.CDRS_WZ_DETAIL.DETOUR_DESC #""",
            "#",
        )
        TableToTable_conversion("wz1", "in_memory", "wz")
        # Joining the Oracle CDRS WZ table
        print str(datetime.datetime.now()) + " Joining the Oracle CDRS WZ table"
        MakeFeatureLayer_management("Construction", "ConstJoin")
        AddJoin_management(
            "ConstJoin", "CDRS_WZ_DETAIL_ID", "wz", "KANROAD_CDRS_WZ_DETAIL_CDRS_WZ_DETAIL_ID", "KEEP_ALL"
        )
        FeatureClassToFeatureClass_conversion("ConstJoin", "in_memory", "CDRS", "#", "ConstJoin.ALERT_STATUS <  3", "#")
        # reformatting the Route name for US routes
        print str(datetime.datetime.now()) + " reformatting the Route name for US routes"
        AddField_management("CDRS", "RouteName", "TEXT", "#", "10")
        routenamed = (
            '!Construction_BEG_LRS_ROUTE![0:1] +str(!Construction_BEG_LRS_ROUTE![3:6]).lstrip("0")'
        )  # calculation expression
        # Calculate the Route names for User Display
        print routenamed
        CalculateField_management("CDRS", "RouteName", routenamed, "PYTHON_9.3", "#")
        AddField_management("CDRS", "STATUS", "TEXT", "#", "10")
        AddField_management("CDRS", "Alert_Status_I", "LONG", "#", "#")
        CalculateField_management("CDRS", "Alert_Status_I", "!Construction_ALERT_STATUS!", "PYTHON_9.3", "#")
        # Assigning projection for KanRoad CDRS Alert Route Layer
        print str(datetime.datetime.now()) + " Assigning projection for KanRoad CDRS Alert Route Layer"
        DefineProjection_management("CDRS", lambertCC)
        # reformatting the Route name for US routes
        print str(datetime.datetime.now()) + " reformatting the Route name for US routes"
        MakeFeatureLayer_management("CDRS", "ACTIVERoutes", '"Construction_ALERT_STATUS" =  2')
        CalculateField_management("ACTIVERoutes", "STATUS", '"Active"', "PYTHON_9.3", "#")

        MakeFeatureLayer_management(
            "CDRS", "ClosedRoutes", '"Construction_ALERT_STATUS" =  2 AND "Construction_FEA_CLOSED" =  1'
        )
        CalculateField_management("ClosedRoutes", "STATUS", '"Closed"', "PYTHON_9.3", "#")

        MakeFeatureLayer_management("CDRS", "PlannedRoutes", '"Construction_ALERT_STATUS" =  1')
        CalculateField_management("PlannedRoutes", "STATUS", '"Planned"', "PYTHON_9.3", "#")

        # copying joined oracle tables to memory for loading in Wichway Schema
        print str(datetime.datetime.now()) + " copying joined oracle tables to memory for loading in Wichway Schema"
        FeatureClassToFeatureClass_conversion(sdeKandriveConstruction, "in_memory", "CDRS_Segments", "#", "#")

        # delete rows in the destination feature class
        DeleteRows_management("CDRS_Segments")

        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to the searchCursorFields and the
        # insertCursorFields lists and make sure that it is in the same position in the list order for both of
        # them.
        # Besides 'LoadDate', the order does not matter, so long as each field name in the
        # searchCursorFields has a counterpart in the insertCursorFields and vice versa.
        # 'LoadDate' should always be last for the insertCursorFields as it is appended to each row after all
        # of the other items from the searchCursorFields.
        ###############################################################################################################

        featuresToTransfer = list()

        # searchCursorFields go to "in_memory\CDRS". (Input table)
        searchCursorFields = [
            "SHAPE@",
            "RouteName",
            "Construction_BEG_STATE_LOGMILE",
            "Construction_END_STATE_LOGMILE",
            "Construction_BEG_COUNTY_NAME",
            "Construction_ALERT_DATE",
            "Construction_COMP_DATE",
            "Construction_ALERT_TYPE_TXT",
            "Construction_ALERT_DESC_TXT",
            "Construction_VERT_RESTRICTION",
            "Construction_WIDTH_RESTRICTION",
            "Construction_TIME_DELAY_TXT",
            "Construction_PUBLIC_COMMENT",
            "wz_KANROAD_CDRS_WZ_DETAIL_DETOUR_TYPE_TXT",
            "wz_KANROAD_CDRS_WZ_DETAIL_DETOUR_DESC",
            "Construction_CONTACT_NAME",
            "Construction_CONTACT_PHONE",
            "Construction_CONTACT_EMAIL",
            "Construction_ALERT_HYPERLINK",
            "Alert_Status_I",
            "Construction_FEA_CLOSED",
            "STATUS",
            "Construction_ALERT_DIREC_TXT",
            "Construction_BEG_LONGITUDE",
            "Construction_BEG_LATITUDE",
        ]

        # insertCursorFields go to sdeKandriveConstruction. (Output table)
        insertCursorFields = [
            "SHAPE@",
            "RouteName",
            "BeginMP",
            "EndMP",
            "County",
            "StartDate",
            "CompDate",
            "AlertType",
            "AlertDescription",
            "HeightLimit",
            "WidthLimit",
            "TimeDelay",
            "Comments",
            "DetourType",
            "DetourDescription",
            "ContactName",
            "ContactPhone",
            "ContactEmail",
            "WebLink",
            "AlertStatus",
            "FeaClosed",
            "Status",
            "AlertDirectTxt",
            "X",
            "Y",
            "LoadDate",
        ]

        cdrsSearchCursor = daSearchCursor(r"in_memory\CDRS", searchCursorFields)

        for cdrsCursorItem in cdrsSearchCursor:
            featureItem = list(cdrsCursorItem)
            featureItem.append(starttime)
            featuresToTransfer.append(featureItem)

        RemoveJoin_management("ConstJoin", "wz")

        # truncating CDRS segments in WICHWAY SPATIAL
        print str(datetime.datetime.now()) + " truncating CDRS segments in WICHWAY SPATIAL"

        TruncateTable_management(sdeKandriveConstruction)

        cdrsInsertCursor = daInsertCursor(sdeKandriveConstruction, insertCursorFields)

        for cdrsFeature in featuresToTransfer:
            insertOID = cdrsInsertCursor.insertRow(cdrsFeature)
            print "Inserted a row with the OID of: " + str(insertOID)

    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        print errorItem.args[0]
        try:
            del errorItem
        except:
            pass
        raise
    finally:
        try:
            del cdrsSearchCursor
        except:
            pass
        try:
            del cdrsInsertCursor
        except:
            pass
Ejemplo n.º 38
0
def createCountyLinesForEachCounty():
    
    inputCountyLines = r'Database Connections\sdedev_GIS_DEV.sde\SHARED.COUNTY_LINES'
    inputCountyPolygons = r'Database Connections\sdedev_GIS_DEV.sde\SHARED.COUNTIES'
    dissolvedCountyLines = r'Database Connections\countyMapsSQLSDE.sde\CountyLinesDissolved'
    bufferedCountyPolygons = r'Database Connections\countyMapsSQLSDE.sde\CountiesBuffered'
    loadedCounties = 'loadedCounties'
    tempCountyLines = r'in_memory\tempCountyLines'
    outputCountyLines = r'Database Connections\countyMapsSQLSDE.sde\CountyLinesIntersected'
    bufferCursorFields = ["OBJECTID"]
    
    # Need to 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.
    
    arcpy.Dissolve_management(inputCountyLines, dissolvedCountyLines)
    arcpy.Buffer_analysis(inputCountyPolygons, bufferedCountyPolygons, "15500 Feet")
    
    bufferedCountyPolygonList = list()
    outputFeatureList = list()
    
    # 1st SearchCursor
    newCursor = daSearchCursor(bufferedCountyPolygons, bufferCursorFields)
    for newRow in newCursor:
        bufferedCountyPolygonList.append(list(newRow))
        
    if 'newCursor' in locals():
        del newCursor
    else:
        pass
    
    arcpy.MakeFeatureLayer_management(bufferedCountyPolygons, loadedCounties)
    
    for listedRow in bufferedCountyPolygonList:
        selectNumber = listedRow[0]
        
        whereClause = " \"OBJECTID\" = '" + str(selectNumber)  + "' "
        arcpy.SelectLayerByAttribute_management(loadedCounties, "NEW_SELECTION", whereClause)
        
        arcpy.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
    
    
    # 1st CreateFeatures_management
    # 1st, 2nd AddField_management
    lambertProjectionLocationKansas = r"\\gisdata\ArcGIS\GISdata\NAD_83_Kansas_Lambert_Conformal_Conic_Feet.prj"
    arcpy.CreateFeatureclass_management(r'Database Connections\countyMapsSQLSDE.sde', "CountyLinesIntersected", "POLYLINE", "", "", "", lambertProjectionLocationKansas)
    
    arcpy.AddField_management(outputCountyLines, "County_Number", "DOUBLE", "", "", "")
    
    arcpy.AddField_management(outputCountyLines, "County_Name", "TEXT", "", "", "55")
    
    print "First Intersected County Row: " + str(outputFeatureList[0])
    
    # 1st InsertCursor
    # Use this again later. Very useful. -- Will need when trying to deserialize arcpy objects from multiprocessing and
    # then write them to a feature class, since I'll have to call arcpy.point(array) where array is an x,y coord in a
    # list format prior to writing them to a gdb or sde.
    newCursor = daInsertCursor(os.path.join(r'Database Connections\countyMapsSQLSDE.sde', 'CountyLinesIntersected'), ["SHAPE@", "County_Number", "County_Name"])
    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
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 labelAngleNormalization():
    
    if "COUNTY_NAME" not in arcpy.ListFields(countyRoadNameRosette):
        arcpy.AddField_management(countyRoadNameRosette, "COUNTY_NAME", "TEXT", "", "", "55")
    else:
        pass
    
    newCursor = daSearchCursor(countyBorderFeature, countyBorderFields)
    
    countyTranslationDictionary = dict()
    
    for countyBorderItem in newCursor:
        if countyBorderItem[4] not in countyTranslationDictionary:
            countyTranslationDictionary[countyBorderItem[4]] = countyBorderItem[3]
        else:
            pass
    
    if "newCursor" in locals():
        del newCursor
    else:
        pass
    
    
    newCursor = daUpdateCursor(countyRoadNameRosette, countyRoadNameRosetteFields)
    
    for countyPointItem in newCursor:
        countyPointItem = list(countyPointItem)
        
        # Takes the remainder of the angle divided by 360.
        countyPointItem[0] = math.fmod(countyPointItem[0], 360) # Uses fmod due to floating point issues with the modulo operator in python.
        
        if countyPointItem[0] >= 250 and countyPointItem[0] <= 290:
            countyPointItem[0] = 270
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)
            
        elif countyPointItem[0] >= 160 and countyPointItem[0] <= 200:
            countyPointItem[0] = 180
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)
            
        elif countyPointItem[0] >= 70 and countyPointItem[0] <= 110:
            countyPointItem[0] = 90
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)
            
        elif (countyPointItem[0] >= 0 and countyPointItem[0] <= 20) or (countyPointItem[0] >= 340 and countyPointItem[0] <= 360):
            countyPointItem[0] = 0
            if countyPointItem[2] in countyTranslationDictionary:
                countyPointItem[1] = countyTranslationDictionary[countyPointItem[2]]
            else:
                countyPointItem[1] = ""
            newCursor.updateRow(countyPointItem)
            
        else:
            print "Deleting row for having an angle more than 20 degrees away from a cardinal direction."
            newCursor.deleteRow()
            
         
    if "newCursor" in locals():
        del newCursor
    else:
        pass
    
    
    print "Label angle normalization complete!"
    print "Done extending and intersecting road features." # Need to break this into two pieces and pass some of the inmemorylayers
def localRouteNumbering():
    tempDesc = Describe(routeFeaturesFC)
    print("Calculating LRS Key sub-parts for features in " +
          returnFeatureClass(tempDesc.catalogPath) + ".")
    OIDFieldName = tempDesc.OIDFieldName

    try:
        del tempDesc
    except:
        pass

    # ReAdd the fields that we're interested in, in the correct order.
    # sortPointDist will be appended later, making it [-1] and 'LRS_UNIQUE_IDENT1' will be [-2].
    fieldsToUse = [
        OIDFieldName, 'SHAPE@', 'LABEL', 'LRS_ROUTE_PREFIX', 'LRS_ROUTE_NUM',
        'LRS_UNIQUE_IDENT', 'LRS_UNIQUE_IDENT1'
    ]

    currentFields = fieldsToUse

    shapeTokenPosition = 1

    uniqueCountyCodeDict = dict()
    countyCodeFieldsList = ['KDOT_COUNTY_L', 'KDOT_COUNTY_R']
    newCursor = daSearchCursor(routeFeaturesFC, countyCodeFieldsList)
    for cursorRow in newCursor:
        uniqueCountyCodeDict[str(cursorRow[0])] = 1
        uniqueCountyCodeDict[str(cursorRow[1])] = 1

    try:
        del newCursor
    except:
        pass

    uniqueCountyCodeList = list()

    for uniqueCountyCode in uniqueCountyCodeDict.keys():
        uniqueCountyCodeList.append(uniqueCountyCode)

    try:
        del uniqueCountyCodeDict
    except:
        pass

    try:
        uniqueCountyCodeList.remove('None')
    except:
        pass

    sortedUniqueCountyCodes = sorted(
        uniqueCountyCodeList
    )  # No need to specify a key since it's one column.

    for uniqueCountyCodeItem in sortedUniqueCountyCodes:
        print('Selecting features based on countyCode: ' +
              str(uniqueCountyCodeItem) + '.')
        routeFeaturesList = list()

        uniqueLabelDict = dict()

        # This should include a check for LRS_PREFIX = 'L' when the KDOT_LRS_KEY IS NULL, instead of taking everything that has a NULL
        # KDOT LRS_KEY. Need another parenthesis to group the condition inside the current parenthesis.
        selectionQuery1 = """ KDOT_COUNTY_L = '""" + str(
            uniqueCountyCodeItem
        ) + """' AND ((KDOT_LRS_KEY IS NULL AND LRS_PREFIX = 'L') OR KDOT_LRS_KEY LIKE '%L%') """
        selectionQuery2 = """ KDOT_COUNTY_L IS NULL AND KDOT_COUNTY_R = '""" + str(
            uniqueCountyCodeItem
        ) + """' AND ((KDOT_LRS_KEY IS NULL AND LRS_PREFIX = 'L') OR KDOT_LRS_KEY LIKE '%L%') """

        labelField = ['LABEL']
        newCursor = daSearchCursor(routeFeaturesFC, labelField,
                                   selectionQuery1)
        for cursorRow in newCursor:
            uniqueLabelDict[str(cursorRow[0])] = 1

        try:
            del newCursor
        except:
            pass

        newCursor = daSearchCursor(routeFeaturesFC, labelField,
                                   selectionQuery2)
        for cursorRow in newCursor:
            uniqueLabelDict[str(cursorRow[0])] = 1

        try:
            del newCursor
        except:
            pass

        countyLocalNumber = 0

        # Narrow the features that are looked at further.
        ### Change this to just give you the features instead of    ###
        ### cursoring them back out.                                ###
        ### Figure out a way to create dicts/lists that store the features
        ### in the way that you want them instead of having to run another
        ### separate pair of selects after this.
        for uniqueLabelKey in uniqueLabelDict.keys():
            if uniqueLabelKey is not 'None':
                # Labels with single quotes cause problems in selections.
                if str.find(uniqueLabelKey, "'") > -1:
                    # So, escape them by replacing individual single quotes with double single quotes.
                    uniqueLabelKey = str.replace(uniqueLabelKey, "'", "''")
                else:
                    pass
                print("Using the LABEL field value of: " +
                      str(uniqueLabelKey) + ".")
                countyLocalNumber += 1
                selectionQuery3 = selectionQuery1 + """ AND LABEL = '""" + str(
                    uniqueLabelKey) + """' """
                selectionQuery4 = selectionQuery2 + """ AND LABEL = '""" + str(
                    uniqueLabelKey) + """' """

                labeledRouteFeaturesList = list()
                firstCounter = 0
                newCursor = daSearchCursor(routeFeaturesFC, currentFields,
                                           selectionQuery3)
                for cursorRow in newCursor:
                    firstCounter += 1
                    labeledRouteFeaturesList.append(list(cursorRow))

                try:
                    del newCursor
                except:
                    pass
                print("FirstCounter found : " + str(firstCounter) +
                      " segments.")

                secondCounter = 0
                newCursor = daSearchCursor(routeFeaturesFC, currentFields,
                                           selectionQuery4)
                for cursorRow in newCursor:
                    secondCounter += 1
                    labeledRouteFeaturesList.append(list(cursorRow))

                try:
                    del newCursor
                except:
                    pass

                print("SecondCounter found : " + str(secondCounter) +
                      " segments.")

                sortedLabeledRouteFeaturesList = addDistanceAndSort(
                    labeledRouteFeaturesList, shapeTokenPosition)

                del labeledRouteFeaturesList

                labelUniqueNumber = 0
                previousFeatureGeom = None
                outputFeaturesDict = dict()
                for sortedLabeledRouteFeatureItem in sortedLabeledRouteFeaturesList:
                    if previousFeatureGeom == None:
                        # This is the first feature of this label.
                        # Don't need to check for incrementing the labelUniqueNumber.
                        # Just assign the current countyLocalNumber to this feature.
                        # Then, set the previousFeatureGeom to this feature's shape.
                        previousFeatureGeom = sortedLabeledRouteFeatureItem[
                            shapeTokenPosition]
                    else:
                        # Check to see if this feature's firstpoint or lastpoint are
                        # a match for the previous feature's firstpoint or lastpoint.
                        thisFeatureGeom = sortedLabeledRouteFeatureItem[
                            shapeTokenPosition]
                        ## This part needs work because it always fails. :(.
                        ## Create a function to check the arrays for relevant matching values instead.
                        ## And let it "match" when there are points that are within the feature tolerance
                        ## of one another. The non-matching is most likely a problem with floating point
                        ## math and equalities. -- See videolog lookup C# for ideas, if needed.

                        # Change this to look at math.abs(firstPoint.X - other.firstPoint.X) < 2*Epsilon,
                        # and math.abs(firstPoint.Y - other.firstPoint.Y) < 2*Epsilon
                        # Since each Point is a Python object and they won't have the same
                        # identity in Python when it performs a comparison on them.
                        # The only time that this will work correctly is when you have
                        # two variable names referencing the same object
                        # (in the same memory location).
                        if polylineStartEndPointsMatch(
                                thisFeatureGeom, previousFeatureGeom,
                                currentXYTolerance) == True:
                            # The feature is contiguous without a gap. The labelUniqueNumber doesn't need to be incremented.
                            # Assign the county code as it's routeNumber and the labelUniqueNumber as its unique ID.
                            pass
                        else:
                            # If not, increment the labelUniqueNumber by 1
                            # prior to assignment on this feature.
                            labelUniqueNumber += 1

                        # If greater than 99, then you have to split it so that part of it goes into LRS_UNIQUE_IDENT
                        # and part of it goes into LRS_UNIQUE_IDENT1.
                        if labelUniqueNumber > 99:
                            onesAndTens = labelUniqueNumber % 100
                            hundredsAndThousands = labelUniqueNumber / 100
                            pass
                        else:
                            onesAndTens = labelUniqueNumber
                            hundredsAndThousands = 0
                        sortedLabeledRouteFeatureItem[-2] = str(
                            onesAndTens).zfill(2)  ## 2 chars
                        sortedLabeledRouteFeatureItem[-3] = str(
                            hundredsAndThousands).zfill(
                                1
                            )  ## 2 chars # Should only be 1char, but /shrug
                        sortedLabeledRouteFeatureItem[-4] = str(
                            countyLocalNumber).zfill(5)  ## 5 chars
                        # Then, set the previousFeatureGeom to this feature's shape.
                        previousFeatureGeom = sortedLabeledRouteFeatureItem[
                            shapeTokenPosition]

                    print(
                        "Adding a feature to the outputFeaturesDict with a countyLocalNumber of: "
                        + str(countyLocalNumber) +
                        " and a labelUniqueNumber of: " +
                        str(labelUniqueNumber) + ".")
                    outputFeaturesDict[sortedLabeledRouteFeatureItem[
                        0]] = sortedLabeledRouteFeatureItem[:-1]

                newCursor = daUpdateCursor(routeFeaturesFC, currentFields,
                                           selectionQuery3)

                for cursorRow in newCursor:
                    if cursorRow[0] in outputFeaturesDict.keys():
                        newCursor.updateRow(outputFeaturesDict[cursorRow[0]])

                try:
                    del newCursor
                except:
                    pass

                newCursor = daUpdateCursor(routeFeaturesFC, currentFields,
                                           selectionQuery4)

                for cursorRow in newCursor:
                    if cursorRow[0] in outputFeaturesDict.keys():
                        newCursor.updateRow(outputFeaturesDict[cursorRow[0]])

                try:
                    del newCursor
                except:
                    pass

                try:
                    del sortedLabeledRouteFeaturesList
                except:
                    pass

            else:
                pass

            #Cleanup
            try:
                del sortedLabeledRouteFeaturesList
            except:
                pass
        try:
            del sortedLabeledRouteFeaturesList
        except:
            pass
def changedFeaturesImport(sourceFeatures, targetFeatures):
    # 1.) Make an in_memory copy of the centerlines.
    #### A field map would have to be created for each dissolved feature layer, so it's not really worth it.
    # 2.) Get a list of all of the unique Keys
    # 3.) Loop through the list of unique Keys
    # 4.) For each Key, select all the features with that Key.
    # 5.) Count selected features.
    # 6.) Make a new layer or dissolved layer from this selection.
    # 7.) Count the number of dissolved features.
    # 8a.) If the number of dissolved features is 0, then append the error to the error file
    #       and go on to the next Key in the loop.
    # 8b.) Else, spatially select features in the original feature class with 'SHARE_A_LINE_SEGMENT_WITH'.
    # 9.) From the spatial select, reselect features that have the same Key.
    # 10.) Count to make sure that at least one feature is selected.
    # 11.) If so, delete that feature.
    # 12.) Cursor the features out of the dissolve layer.
    # 13.) Insert the features from the dissolve layer into the in_memory copy of the centerlines.
    # 14.) When the loop is complete, save the in_memory copy of the centerlines
    #       to a gdb on disk.
    
    # Won't work for shapefiles. Hopefully you're not using those though.
    targetFeaturesCopy = targetFeatures + '_Copy'
    try:
        del targetFeatureLayer
    except:
        pass
    targetFeatureLayer = returnFeatureClass(targetFeaturesCopy) + '_FL'
    try:
        del sourceFeatureLayer
    except:
        pass
    sourceFeatureLayer = returnFeatureClass(sourceFeatures) + '_FL'
    
    # Perform cleanup to prevent object creation collisions.
    layersOrFCsToRemove = [targetFeaturesCopy, targetFeatureLayer, sourceFeatureLayer]
    for layerOrFCItem in layersOrFCstoRemove:
        if Exists(layerOrFCItem):
            try:
                Delete_management(layerOrFCItem)
            except:
                pass
        else:
            pass
    
    # 1a.) Make an copy of the simplified and flipped centerlines to modify with dissolves.
    CopyFeatures_management(targetFeatures, targetFeaturesCopy)
    
    # 1b.) Add the ReviewUser and ReviewInfo fields to the copy if they do not already exist.
    #       That way, the information from the edits can flow through to future edit sessions
    #       and error checks.
    tfcDesc = Describe(targetFeaturesCopy)
    tfcFields = tfcDesc.fields
    tfcFieldNames = [x.name for x in tfcFields]
    
    # Check for ReviewUser field in the targetFeaturesCopy, then add it if missing.
    if 'ReviewUser' not in tfcFieldNames:
        #ReviewUser (String, 50)
        AddField_management(targetFeaturesCopy, 'ReviewUser', "TEXT", "", "", 50, 'ReviewUser', nullable)
    else:
        pass
    
    # Check for ReviewInfo field in the targetFeaturesCopy, then add it if missing.
    if 'ReviewInfo' not in tfcFieldNames:
        #ReviewInfo (String, 250)
        AddField_management(targetFeaturesCopy, 'ReviewInfo', "TEXT", "", "", 250, 'ReviewInfo', nullable)
    else:
        pass
    
    sourceSelectionQuery = ''' "''' + str(uniqueKeyFieldToUse) + '''" IS NOT NULL AND "''' + str(uniqueKeyFieldToUse) + '''" IN ('''
    sourceSelectionQuery = sourceSelectionQuery[:-2] + ''') '''
    
    MakeFeatureLayer_management(targetFeaturesCopy, targetFeatureLayer)
    MakeFeatureLayer_management(sourceFeatures, sourceFeatureLayer)
    
    # 2.) Get a list of all of the unique Keys in the source.
    ############ Modify this process to only get a list of Keys that have more than one feature.
    ############ everything else can be skipped for the purpose of dissolving.
    uniqueKeyFieldList = [str(uniqueKeyFieldToUse)]
    newCursor = daSearchCursor(sourceFeatureLayer, uniqueKeyFieldList)
    uniqueKeysDict = dict()
    for cursorRow in newCursor:
        uniqueKeysDict[str(cursorRow[0])] = 1
    
    try:
        del newCursor
    except:
        pass
    
    uniqueKeysList = uniqueKeysDict.keys()
    try:
        uniqueKeysList.remove('None')
    except:
        print("Could not remove 'None' from the list of uniqueKeys since it was not a part of the list.")
    
    print("Unique Key list creation successful.")
    print('Found ' + str(len(uniqueKeysList)) + ' unique Keys in the changed features.')
    
    #Use multiSelection instead.
    multiSelectionQuery = ''' "''' + str(uniqueKeyFieldToUse) + '''" IS NOT NULL AND "''' + str(uniqueKeyFieldToUse) + '''" IN ('''
    multiCounter = 0
    
    # 3.) Loop through the list of unique Keys
    for uniqueKeyItem in uniqueKeysList:
        # 4.) For groups of 2000 Keys, select all the features with those Keys.
        if multiCounter <= 1999:
            multiSelectionQuery += """'""" + str(uniqueKeyItem) + """'""" + """, """
            multiCounter += 1
        else:
            # Add the current item
            multiSelectionQuery += """'""" + str(uniqueKeyItem) + """'""" + """, """
            # Then, remove the trailing ", " and add a closing parenthesis.
            multiSelectionQuery = multiSelectionQuery[:-2] + ''') '''
            
            featureReplacement(sourceFeatureLayer, targetFeatureLayer, multiSelectionQuery)
            
            multiSelectionQuery = ''' "''' + str(uniqueKeyFieldToUse) + '''" IS NOT NULL AND "''' + str(uniqueKeyFieldToUse) + '''" IN ('''
            multiCounter = 0
    
    # After the for loop, if there is still anything remaining which was unselected in the
    # the previous multiSelectionQuery steps.
    # Remove the trailing ", " and add a closing parenthesis.
    multiSelectionQuery = multiSelectionQuery[:-2] + """) """
    
    featureReplacement(sourceFeatureLayer, targetFeatureLayer, multiSelectionQuery)
Ejemplo n.º 43
0
def transferConstructionWeather():
    env.workspace = in_memory
    featuresToTransfer = list()
    try:
        print str(
            datetime.datetime.now()) + ' copying the oracle table to memory'

        # Create an in_memory feature class which to hold the features from
        # the Oracle table.

        FeatureClassToFeatureClass_conversion(sdeCDRS, "in_memory",
                                              "CDRS_Weather", "#")

        # Then, define a projection on it, since the original Oracle table
        # is lacking the proper information.
        DefineProjection_management("in_memory\CDRS_Weather", lambertCC)

        ###############################################################################################################
        # Maintainability information:
        # ToDo:
        # If you need to add another field to transfer between the two, just add it to the searchCursorFields and the
        # insertCursorFields lists and make sure that it is in the same position in the list order for both of
        # them.
        # Besides 'LoadDate', the order does not matter, so long as each field name in the
        # searchCursorFields has a counterpart in the insertCursorFields and vice versa.
        # 'LoadDate' should always be last for the insertCursorFields as it is appended to each row after all
        # of the other items from the searchCursorFields.
        ###############################################################################################################

        # searchCursorFields go to "in_memory\CDRS". (Input table)
        # Removed 'GEOMETRY', then replaced functionality with 'SHAPE@'.
        # Also removed 'OBJECTID', 'RPT_BY_NAME', 'RPT_BY_PHONE',
        # 'RPT_BY_EMAIL', 'CONTACT_NAME', 'CONTACT_PHONE', 'CONTACT_EMAIL',
        # 'BEG_LATITUDE', 'BEG_LONGITUDE', 'BEG_REF_POST', 'END_REF_POST',
        # 'END_LATITUDE', 'END_LONGITUDE', 'INTERNAL_COMMENT',
        # 'WIDTH_RESTRICTION',	'VERT_RESTRICTION', 'WEIGHT_RESTRICTION',
        # 'SPEED_RESTRICTION', 'PUBLIC_VIEW', 'DCAM_COMMENT', 'DCAM_DATE',
        # 'DISPLAY_MAP', 'LINE_COLOR', 'CDRS_ALERT_ROUTE_ID', 'ALERT_ID',
        # 'ALERT_DATE', 'COMP_DATE', 'BEG_COUNTY_NAME',
        # 'END_LRS_KEY', 'END_LRS_ROUTE',	'END_COUNTY_NAME',
        # 'BEG_LRS_DIREC_TXT', 'END_LRS_DIREC_TXT', 'TIME_DELAY_TXT',
        # 'CDRS_WZ_DETAIL_ID', 'CDRS_FHWA_ID', 'CONST_PROJ_NUM',
        # 'PUBLIC_COMMENT', 'OFFICE_NAME', 'NEW_NOTIFICATION',
        # 'EMAIL_REMINDER', 'NOTIFICATION_SENT', 'LOC_ENTRY_TYPE',
        # 'ALERT_HYPERLINK', 'GIS_VIEW',
        # 'END_COUNTY_NUMBER', 'ALERT_TYPE_TXT', 'ALERT_STATUS',
        # 'CLOSED_MSG_SENT', 'ALERT_INSERT_DT', 'FEA_CLOSED'
        # Public Comment is where to get the output text data from.
        ######################################################################
        searchCursorFields = [
            'SHAPE@', 'ADMIN_OWNER', 'BEG_LRS_KEY', 'ALERT_DIREC_TXT',
            'ALERT_DESC_TXT', 'BEG_COUNTY_NUMBER', 'BEG_STATE_LOGMILE',
            'END_STATE_LOGMILE', 'LENGTH', 'DISTRICT', 'AREA', 'ROUTE',
            'BEG_LRS_ROUTE', 'BEG_DESC', 'END_DESC', 'SITE_CR', 'LAST_UPDATE',
            'START_DATE', 'EXPIRE_DATE'
        ]

        # insertCursorFields go to kandrive_spatial.DBO.Conditions. (Output table)
        # Removed 'GEOMETRY' and 'GEOMETRY.STLength()', then replaced their
        # functionality with 'SHAPE@'.
        # Also removed 'OBJECTID'
        ######################################################################
        insertCursorFields = [
            'SHAPE@',
            'ADMIN_OWNER',
            'LRS_KEY',
            'LANE_DESCRIPTION',
            'ROAD_COND_TEXT',
            'COUNTY_NO',
            'BEG_STATE_LOGMILE',
            'END_STATE_LOGMILE',
            'SEG_LENGTH_MILES',
            'SNOW_DIST',
            'SNOW_AREA',
            'RD_SUFX_SUBC',
            'ROUTE_ID',
            'BEG_DESC',
            'END_DESC',
            'SITE_CR',
            'LAST_UPDATE',  ### End of directly transfered columns. Next are set columns.
            'STALE_MSG',
            'UNIQUE_ID',
            'RCRS_ROADS_ID',
            'SNOW_SUBAREA',
            'ROAD_CONDITION',
            'RE_OPENING',
            'CLOSED_MSG_SENT',
            'CLOSED_FROM',
            'CLOSED_TO',
            'ACCOMMODATION',
            'USER_ID',
            'CLOSED_COND',
            'MSG_CODE',
            'LINE_COLOR',
            'MSG_SENT',
            'SNOW_ICE_CATEGORY',
            'RCRSP_VIEW',
            ## End of set columns. Next are calculated columns
            'SEGMENT_ID',
            'LRS_PREFIX',
            'LRS_SUFFIX',
            'LRS_SUBCLASS',
            'RT_NUMBER',
            'BEG_POINT_DESC',
            'END_POINT_DESC',
            'RCRSP_DIST',
            'SNICE_BEGIN',
            'SNICE_END',
            'REPORT_TIME',
            'ROAD_COND_TIME'
        ]
        # 46 Total with 29 following LAST_UPDATE

        weatherTypesString = "('Flooding', 'Fog', 'Blowing Dust/Smoke', 'Wind Damage')"
        whereClause = """ALERT_STATUS = 2 AND FEA_CLOSED = 1 AND ALERT_TYPE_TXT = 'Road Closing' AND ALERT_DESC_TXT IN """ + weatherTypesString

        cdrsSearchCursor = daSearchCursor(r"in_memory\CDRS_Weather",
                                          searchCursorFields, whereClause)

        for cdrsCursorItem in cdrsSearchCursor:
            featureItem = list(cdrsCursorItem)
            ## Copied columns
            copiedFeatureItem = featureItem[:-2]
            lrsKey = featureItem[2]
            startDateCDRS = featureItem[-2]
            startDateStr = startDateCDRS.strftime('%m/%d/%y')
            expDateCDRS = featureItem[-1]
            expDateStr = expDateCDRS.strftime('%m/%d/%y')
            ## Set Columns
            copiedFeatureItem.append(0)  ## STALE_MSG
            copiedFeatureItem.append(0)  ## UNIQUE_ID
            copiedFeatureItem.append(9999)  ## RCRS_ROADS_ID
            copiedFeatureItem.append(9)  ## SNOW_SUBAREA
            copiedFeatureItem.append(
                11)  ## ROAD_CONDITION should always == 11, for closed.
            copiedFeatureItem.append(None)  ## RE_OPENING
            copiedFeatureItem.append(None)  ## CLOSED_MSG_SENT
            copiedFeatureItem.append(None)  ## CLOSED_FROM
            copiedFeatureItem.append(None)  ## CLOSED_TO
            copiedFeatureItem.append(None)  ## ACCOMMODATION
            copiedFeatureItem.append(100)  ## USER_ID
            copiedFeatureItem.append(2)  ## CLOSED_COND
            copiedFeatureItem.append('0000')  ## MSG_CODE
            copiedFeatureItem.append(255)  ## LINE_COLOR
            copiedFeatureItem.append(0)  ## MSG_SENT
            copiedFeatureItem.append(3)  ## SNOW_ICE_CATEGORY
            copiedFeatureItem.append(3)  ## RCRSP_VIEW
            ## Calculated Columns
            copiedFeatureItem[4] = 'Closed - ' + copiedFeatureItem[
                4]  ## ROAD_COND_TEXT
            copiedFeatureItem.append(
                copiedFeatureItem[12])  ## SEGMENT_ID = ROUTE_ID
            copiedFeatureItem.append(lrsKey[3:4])  ## LRS_PREFIX
            copiedFeatureItem.append(lrsKey[9:10])  ## LRS_SUFFIX
            copiedFeatureItem.append(lrsKey[-1:])  ## LRS_SUBCLASS
            rtNumberToFormat = lrsKey[6:9]
            rtNumberFormatted = int(rtNumberToFormat)
            copiedFeatureItem.append(rtNumberFormatted)  ## RT_NUMBER
            # Only get the first 60 chars on the next two columns.
            copiedFeatureItem.append(
                copiedFeatureItem[13][:60])  ## BEG_POINT_DESC
            copiedFeatureItem.append(
                copiedFeatureItem[14][:60])  ## END_POINT_DESC
            copiedFeatureItem.append(copiedFeatureItem[9])  ## RCRSP_DIST
            copiedFeatureItem.append(startDateStr +
                                     ' 12:04 AM')  ## SNICE_BEGIN
            copiedFeatureItem.append(expDateStr + ' 11:54 PM')  ## SNICE_END
            copiedFeatureItem.append(startDateStr +
                                     ' 12:04 AM')  ## REPORT_TIME
            copiedFeatureItem.append(startDateStr +
                                     ' 12:04 AM')  ## ROAD_COND_TIME

            featuresToTransfer.append(copiedFeatureItem)

        RCRS_InsertCursor = daInsertCursor(kanDriveSpatialConditions,
                                           insertCursorFields)

        for RCRS_Feature in featuresToTransfer:
            insertOID = RCRS_InsertCursor.insertRow(RCRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)

    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement

        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging('KanDrive_Spatial_Conditions_Update',
                            'kandrive_spatial.DBO.Conditions', scriptFailure,
                            startTime, endTime, errorItem.args[0],
                            pythonLogTable)

        try:
            del errorItem
        except:
            pass

        # Reraise the error to stop execution and prevent a success message
        # from being inserted into the table when the script completes.
        raise

    finally:
        try:
            del cdrsSearchCursor
        except:
            pass
        try:
            del RCRS_InsertCursor
        except:
            pass
def transferFeatures():
    env.workspace = in_memory
    featuresToTransfer = list()
    try:
        print str(datetime.datetime.now()) + ' copying the oracle table to memory'
        
        
        # Create an in_memory feature class which to hold the features from
        # the Oracle table.
        FeatureClassToFeatureClass_conversion(sdeCDRS,"in_memory","CDRS","#","ALERT_STATUS <>  3 AND AlertType = 'Road Incident'")
        
        # Then, define a projection on it, since the original Oracle table
        # is lacking the proper information.
        DefineProjection_management("in_memory\CDRS", lambertCC)

        #truncating CDRS segments in KanDrive Spatial
        print str(datetime.datetime.now()) + " truncating Incident segments in KanDrive Spatial."
        TruncateTable_management(kanDriveSpatialIncidents)


        ###############################################################################################################
        # Maintainability information:
        # If you need to add another field to transfer between the two, just add it to both of the
        # tables and give it the same name in both.
        # If you need to add another field to just one, the list comprehension will automatically
        # exclude it.
        #
        # If you need to add another field to transfer between the two and it has to be named
        # different things in each table, you will need to append the matching name to the searchCursorFields list
        # and insertCursorFields list are generated.
        #
        # I.e. if you add a field named "snowFlakeCount" to the CDRS_ALERT_ROUTE table and a field named
        # "snowFlakeCounter" to the kandrive_spatial.DBO.Incidents table, you would need to append
        # "snowFlakeCount" to the searchCursorFields and "snowFlakeCounter" to the insertCursorFields for
        # them to match up and transfer properly. -- If possible, avoid this by naming them both the same thing.
        #
        # If you're having to do several appends, it may be best to just write out all of the field names for
        # each list in the order that you would like for them to be transfered. This is how the field names
        # are listed in the Kandrive_Construction_Update.py script.
        ###############################################################################################################
        
        CDRS_Desc_Object = Describe(r"in_memory\CDRS")
        CDRS_Desc_Fields = [field.name for field in CDRS_Desc_Object.fields]
        Incidents_Desc_Object = Describe(kanDriveSpatialIncidents)
        Incidents_Desc_Fields = [field.name for field in Incidents_Desc_Object.fields]
        
        # This Python list comprehension creates the intersection of the two *_Fields lists
        # and makes sure that the Shape field and Object ID fields are not directly
        # transfered. -- The 'SHAPE@' token indirectly transfers the geometry instead
        # and the Object ID of the target feature class is automatically calculated
        # by the insert cursor.
        searchCursorFields = [fieldName for fieldName in CDRS_Desc_Fields if 
                              fieldName in Incidents_Desc_Fields and
                              fieldName != CDRS_Desc_Object.OIDFieldName and
                              fieldName != Incidents_Desc_Object.OIDFieldName and
                              fieldName != 'Shape']
        
        searchCursorFields.append('SHAPE@')
        
        # Make the insertCursor use the same fields as the searchCursor.
        insertCursorFields = searchCursorFields
        
        print "OIDFieldnames: " + CDRS_Desc_Object.OIDFieldName + " & " + Incidents_Desc_Object.OIDFieldName + "."
        
        print "fieldNames to be used in the searchCursor (and insertCursor):"
        for fieldName in searchCursorFields:
            print fieldName        
        
        Incidents_Where_Clause = "ALERT_TYPE_TXT = 'Road Incident'"
        
        CDRS_SearchCursor = daSearchCursor(r"in_memory\CDRS", searchCursorFields, Incidents_Where_Clause)
        
        for CDRS_CursorItem in CDRS_SearchCursor:
            featureItem = list(CDRS_CursorItem)
            featuresToTransfer.append(featureItem)
        
        Incidents_InsertCursor = daInsertCursor(kanDriveSpatialIncidents, insertCursorFields)
        
        for CDRS_Feature in featuresToTransfer:
            insertOID = Incidents_InsertCursor.insertRow(CDRS_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)
            
        '''
        print "fieldNames to be used in the searchCursor:"
        for fieldName in searchCursorFields:
            print fieldName        
        
        incidents_Where_Clause = "AlertType = 'Road Incident'"
        
        Construction_SearchCursor = daSearchCursor(sdeCDRS, searchCursorFields, incidents_Where_Clause)
        
        for Construction_CursorItem in Construction_SearchCursor:
            featureItem = list(Construction_CursorItem)
            featuresToTransfer.append(featureItem)
        
        Incidents_InsertCursor = daInsertCursor(kanDriveSpatialIncidents, insertCursorFields)
        
        for Construction_Feature in featuresToTransfer:
            insertOID = Incidents_InsertCursor.insertRow(Construction_Feature)
            print "Inserted a row with the OID of: " + str(insertOID)
    
    '''
    except:
        print "An error occurred."
        errorItem = sys.exc_info()[1]
        errorStatement = str(errorItem.args[0])
        print errorStatement
        
        if len(errorStatement) > 253:
            errorStatement = errorStatement[0:253]
        else:
            pass
        endTime = datetime.datetime.now()
        ScriptStatusLogging('KanDrive_Spatial_Incidents_Update', 'kandrive_spatial.DBO.Incidents',
            scriptFailure, startTime, endTime, errorItem.args[0], pythonLogTable)
            
        try:
            del errorItem
        except:
            pass
        
        # Reraise the error to stop execution and prevent a success message
        # from being inserted into the table.
        raise
        
    finally:
        try:
            del CDRS_SearchCursor
        except:
            pass
        try:
            del Incidents_InsertCursor
        except:
            pass