コード例 #1
0
def attachOrphanRedistrictingGroupsToClosestNeighbor(neighborsToAttach):
    tqdm.write('\n')
    tqdm.write(
        '*** Attaching Orphan Redistricting Groups To Closest Neighbor ***')

    contiguousRegions = findContiguousGroupsOfGraphObjects(neighborsToAttach)
    while len(contiguousRegions) > 1:
        tqdm.write('   *** Found {0} Isolated Regions ***'.format(
            len(contiguousRegions)))
        isolatedRegion = contiguousRegions[0]
        closestRegion = findClosestGeometry(originGeometry=isolatedRegion,
                                            otherGeometries=[
                                                region
                                                for region in contiguousRegions
                                                if region is not isolatedRegion
                                            ])

        closestGroupInIsolatedRegion = findClosestGeometry(
            originGeometry=closestRegion, otherGeometries=isolatedRegion)
        closestGroupInClosestRegion = findClosestGeometry(
            originGeometry=isolatedRegion, otherGeometries=closestRegion)

        closestGroupInIsolatedRegion.addNeighbors(
            neighbors=[closestGroupInClosestRegion])
        closestGroupInClosestRegion.addNeighbors(
            neighbors=[closestGroupInIsolatedRegion])

        contiguousRegions = findContiguousGroupsOfGraphObjects(
            neighborsToAttach)
    tqdm.write('   *** No More Orphaned Redistricting Groups ***')
    def test_attachOrphanRedistrictingGroupsToClosestNeighbor_ThreeRegions(
            self):
        testDataFilePath = os.path.join(
            os.path.dirname(__file__),
            'testData/2010-Michigan-KeweenawAndTheThumbRedistrictingGroupInfoHasOrphans.redistdata'
        )
        testData = loadDataFromFile(filePath=testDataFilePath)
        contiguousRegions = findContiguousGroupsOfGraphObjects(testData)
        self.assertEqual(len(contiguousRegions), 3)

        assignNeighboringRedistrictingGroupsForRedistrictingGroups(testData)
        contiguousRegions = findContiguousGroupsOfGraphObjects(testData)
        self.assertEqual(len(contiguousRegions), 1)
コード例 #3
0
def reorganizeAtomicBlockBetweenRedistrictingGroups(redistrictingGroups):
    for redistrictingGroup in redistrictingGroups:
        for borderBlock in redistrictingGroup.borderChildren:
            borderBlock.removeNonIntersectingNeighbors()

    atomicBlockGroupDict = {}
    for redistrictingGroup in redistrictingGroups:
        atomicBlockGroupDict[redistrictingGroup.graphId] = redistrictingGroup.children.copy()

    atomicBlockGroups = atomicBlockGroupDict.values()
    for atomicBlockGroup in atomicBlockGroups:
        contiguousRegions = findContiguousGroupsOfGraphObjects(atomicBlockGroup)
        while len(contiguousRegions) > 1:
            smallestContiguousRegion = min(contiguousRegions,
                                           key=lambda contiguousRegion: len(contiguousRegion))
            smallestContiguousRegionPolygon = polygonFromMultipleGeometries(smallestContiguousRegion)

            otherRegion = None
            otherSplitChildrenList = [x for x in atomicBlockGroups if x is not atomicBlockGroup]
            for otherSplitChildren in otherSplitChildrenList:
                otherSplitChildrenPolygon = polygonFromMultipleGeometries(otherSplitChildren)
                if intersectingPolygons(smallestContiguousRegionPolygon, otherSplitChildrenPolygon):
                    otherRegion = otherSplitChildren
                    break

            if otherRegion is None:
                allBlocksInOtherSplits = [block for blockList in otherSplitChildrenList for block in blockList]
                closestBlock = findClosestGeometry(smallestContiguousRegionPolygon, allBlocksInOtherSplits)
                closestSplit = next((blockList for blockList in otherSplitChildrenList if closestBlock in blockList),
                                    None)
                otherRegion = closestSplit

            for childBlock in smallestContiguousRegion:
                atomicBlockGroup.remove(childBlock)
                childBlock.removeNeighborConnections()

                otherRegion.append(childBlock)
                assignNeighborBlocksFromCandidateBlocks(block=childBlock, candidateBlocks=otherRegion)
            contiguousRegions = findContiguousGroupsOfGraphObjects(atomicBlockGroup)

    for key, value in atomicBlockGroupDict.items():
        groupWithId = next((redistrictingGroup for redistrictingGroup in redistrictingGroups
                            if redistrictingGroup.graphId == key), None)
        groupWithId.children = value

    for redistrictingGroup in redistrictingGroups:
        redistrictingGroup.attachOrphanBlocksToClosestNeighbor()

    return redistrictingGroups
コード例 #4
0
def mergeGroupsOfRedistrictingGroups(groupsOfRedistrictingGroups):
    mergedRedistrictingGroups = []
    with tqdm(total=len(groupsOfRedistrictingGroups)) as pbar:
        for groupOfRedistrictingGroups in groupsOfRedistrictingGroups:
            if len(groupOfRedistrictingGroups) == 1:
                mergedRedistrictingGroups.append(groupOfRedistrictingGroups[0])
            else:
                allBorderBlocks = []
                allBlocks = []
                for redistrictingGroup in groupOfRedistrictingGroups:
                    allBorderBlocks.extend(redistrictingGroup.borderChildren)
                    allBlocks.extend(redistrictingGroup.children)

                # assign block neighbors to former border blocks
                tqdm.write('      *** Starting a merge with {0} border blocks and {1} total blocks ***'.format(
                    len(allBorderBlocks), len(allBlocks)))
                for formerBorderBlock in allBorderBlocks:
                    assignNeighborBlocksFromCandidateBlocks(block=formerBorderBlock,
                                                            candidateBlocks=allBlocks)

                contiguousRegions = findContiguousGroupsOfGraphObjects(allBlocks)

                mergedRedistrictingGroupsForPrevious = []
                for contiguousRegion in contiguousRegions:
                    contiguousRegionGroup = RedistrictingGroup(childrenBlocks=contiguousRegion)
                    # assign block neighbors to former border blocks
                    for borderBlock in contiguousRegionGroup.borderChildren:
                        assignNeighborBlocksFromCandidateBlocks(block=borderBlock,
                                                                candidateBlocks=contiguousRegionGroup.children)
                    contiguousRegionGroup.validateBlockNeighbors()
                    mergedRedistrictingGroupsForPrevious.append(contiguousRegionGroup)
                mergedRedistrictingGroups.extend(mergedRedistrictingGroupsForPrevious)
            pbar.update(1)

    return mergedRedistrictingGroups
コード例 #5
0
def validateContiguousRedistrictingGroups(groupList):
    contiguousRegions = findContiguousGroupsOfGraphObjects(groupList)
    if len(contiguousRegions) > 1:
        saveDataToFileWithDescription(data=contiguousRegions,
                                      censusYear='',
                                      stateName='',
                                      descriptionOfInfo='ErrorCase-GroupsAreNotContiguous')
        plotGraphObjectGroups(contiguousRegions,
                              showDistrictNeighborConnections=True)
        raise ValueError("Don't have a contiguous set of RedistrictingGroups. There are {0} distinct groups".format(
            len(contiguousRegions)))
コード例 #6
0
def mergeContiguousRedistrictingGroups(redistrictingGroupList):
    for redistrictingGroup in redistrictingGroupList:
        redistrictingGroup.clearNeighborGraphObjects()

    assignNeighboringRedistrictingGroupsForRedistrictingGroups(redistrictingGroupList, shouldAttachOrphans=False)
    contiguousRedistrictingGroups = findContiguousGroupsOfGraphObjects(redistrictingGroupList)
    mergedGroupsOfRedistrictingGroups = mergeGroupsOfRedistrictingGroups(contiguousRedistrictingGroups)

    # find and set neighboring geometries
    assignNeighboringRedistrictingGroupsForRedistrictingGroups(mergedGroupsOfRedistrictingGroups)

    validateRedistrictingGroups(mergedGroupsOfRedistrictingGroups)
    validateAllAtomicBlocks()

    return mergedGroupsOfRedistrictingGroups
コード例 #7
0
def splitNonContiguousRedistrictingGroups(redistrictingGroupList):
    tqdm.write('\n')
    tqdm.write('*** Splitting Non-contiguous Redistricting Groups ***')
    groupsToRemove = []
    with tqdm(total=len(redistrictingGroupList)) as pbar:
        for redistrictingGroup in redistrictingGroupList:
            contiguousGroups = findContiguousGroupsOfGraphObjects(redistrictingGroup.children)

            if len(contiguousGroups) > 1:
                groupsToRemove.append(redistrictingGroup)
                for contiguousGroup in contiguousGroups:
                    splitGroup = RedistrictingGroup(childrenBlocks=contiguousGroup)
                    redistrictingGroupList.append(splitGroup)
            pbar.update(1)

    for groupToRemove in groupsToRemove:
        redistrictingGroupList.remove(groupToRemove)
コード例 #8
0
    def validateBlockNeighbors(self):
        contiguousRegions = findContiguousGroupsOfGraphObjects(self.children)
        if len(contiguousRegions) > 1:
            saveDataToFileWithDescription(data=[self, contiguousRegions],
                                          censusYear='',
                                          stateName='',
                                          descriptionOfInfo='ErrorCase-BlocksNotContiguous')
            plotGraphObjectGroups(contiguousRegions, showDistrictNeighborConnections=True)
            plotBlocksForRedistrictingGroup(self, showBlockNeighborConnections=True, showBlockGraphIds=True)
            raise RuntimeError("Don't have a contiguous set of AtomicBlocks. There are {0} distinct groups.".format(
                len(contiguousRegions)))

        for block in self.children:
            neighborBlocksNotInGroup = [neighborBlock for neighborBlock in block.allNeighbors
                                        if neighborBlock not in self.children]
            if len(neighborBlocksNotInGroup):
                saveDataToFileWithDescription(data=[self, block],
                                              censusYear='',
                                              stateName='',
                                              descriptionOfInfo='ErrorCase-BlockHasNeighborOutsideRedistrictingGroup')
                plotBlocksForRedistrictingGroup(self, showBlockNeighborConnections=True, showBlockGraphIds=True)
                raise RuntimeError("Some blocks have neighbor connections with block outside the redistricting group")
コード例 #9
0
def mergeCandidatesIntoPreviousGroups(candidates):
    mergedCandidates = []
    for candidate in candidates:

        # group redistricting groups together based on previous parent
        parentDict = {}
        for redistrictingGroup in candidate:
            # if it doesn't have a previous parent, that means it wasn't broken up, so we will just let is pass through
            if redistrictingGroup.previousParentId is None:
                parentDict[redistrictingGroup.graphId] = [redistrictingGroup]
            else:
                if redistrictingGroup.previousParentId in parentDict:
                    parentDict[redistrictingGroup.previousParentId].append(
                        redistrictingGroup)
                else:
                    parentDict[redistrictingGroup.previousParentId] = [
                        redistrictingGroup
                    ]

        # merge the grouped groups together
        mergedRedistrictingGroups = []
        with tqdm(total=len(parentDict)) as pbar:
            for redistrictingGroupList in parentDict.values():
                if len(redistrictingGroupList) == 1:
                    mergedRedistrictingGroups.append(redistrictingGroupList[0])
                else:
                    allBorderBlocks = []
                    allBlocks = []
                    for redistrictingGroup in redistrictingGroupList:
                        allBorderBlocks.extend(
                            redistrictingGroup.borderChildren)
                        allBlocks.extend(redistrictingGroup.children)

                    # assign block neighbors to former border blocks
                    tqdm.write(
                        '      *** Starting a merge with {0} border blocks and {1} total blocks ***'
                        .format(len(allBorderBlocks), len(allBlocks)))
                    for formerBorderBlock in allBorderBlocks:
                        assignNeighborBlocksFromCandidateBlocks(
                            block=formerBorderBlock, candidateBlocks=allBlocks)

                    contiguousRegions = findContiguousGroupsOfGraphObjects(
                        allBlocks)

                    mergedRedistrictingGroupsForPrevious = []
                    for contiguousRegion in contiguousRegions:
                        contiguousRegionGroup = RedistrictingGroup(
                            childrenBlocks=contiguousRegion)
                        # assign block neighbors to former border blocks
                        for borderBlock in contiguousRegionGroup.borderChildren:
                            assignNeighborBlocksFromCandidateBlocks(
                                block=borderBlock,
                                candidateBlocks=contiguousRegionGroup.children)
                        contiguousRegionGroup.validateBlockNeighbors()
                        mergedRedistrictingGroupsForPrevious.append(
                            contiguousRegionGroup)
                    mergedRedistrictingGroups.extend(
                        mergedRedistrictingGroupsForPrevious)
                pbar.update(1)

        mergedCandidates.append(mergedRedistrictingGroups)

    return mergedCandidates