コード例 #1
0
    def getPopulationEnergySplit(self, alignment, shouldDrawGraph=False):
        polygonSplitResult = self.getPopulationEnergyPolygonSplit(alignment=alignment, shouldDrawGraph=shouldDrawGraph)
        polygonSplitResultType = polygonSplitResult[0]
        if polygonSplitResultType is SplitType.NoSplit:
            return SplitType.NoSplit, None
        elif polygonSplitResultType is SplitType.ForceSplitAllBlocks:
            return SplitType.ForceSplitAllBlocks, None

        polygonSplits = polygonSplitResult[1]

        aSplitPolygon = polygonSplits[0]
        bSplitPolygon = polygonSplits[1]

        if polygonSplitResultType is SplitType.SplitIncludedInSeam:
            seamOnEdge = True
            seamSplitPolygon = None
        else:
            seamOnEdge = False
            seamSplitPolygon = polygonSplitResult[2]

        aSplit = []
        bSplit = []
        seamSplit = []
        for block in self.children:
            if doesPolygonContainTheOther(container=aSplitPolygon, target=block.geometry, ignoreInteriors=False):
                aSplit.append(block)
            elif doesPolygonContainTheOther(container=bSplitPolygon, target=block.geometry, ignoreInteriors=False):
                bSplit.append(block)
            elif not seamOnEdge and doesPolygonContainTheOther(container=seamSplitPolygon, target=block.geometry,
                                                               ignoreInteriors=False):
                seamSplit.append(block)
            # elif allIntersectingPolygons(seamSplitPolygon, block.geometry):
            #     seamSplit.append(block)
            #     plotPolygons([block.geometry])
            else:
                saveDataToFileWithDescription(data=[self, alignment, aSplitPolygon, bSplitPolygon, seamSplitPolygon,
                                                    block.geometry, seamOnEdge, polygonSplitResultType],
                                              censusYear='',
                                              stateName='',
                                              descriptionOfInfo='ErrorCase-CouldNotFindContainerForBlock')
                plotPolygons([aSplitPolygon, bSplitPolygon, seamSplitPolygon, block.geometry])
                raise RuntimeError("Couldn't find a container for block: {0}".format(block.geometry))

        aSplitPopulation = sum(block.population for block in aSplit)
        bSplitPopulation = sum(block.population for block in bSplit)

        if aSplitPopulation < bSplitPopulation:
            aSplit += seamSplit
        else:
            bSplit += seamSplit

        if shouldDrawGraph:
            plotGraphObjectGroups(graphObjectGroups=[aSplit, bSplit])

        return SplitType.NormalSplit, (aSplit, bSplit)
コード例 #2
0
ファイル: geographyHelper.py プロジェクト: mgmartinelli/CDD
def deflationScore(polygon, shouldPlotResult=False):
    exteriorPolygon = Polygon(polygon.exterior)
    stepSize = 1.0 / 60.0 / 60.0
    stepSize = 0.01
    count = 0
    while True:
        deflateValue = stepSize * count
        deflatedPolygon = exteriorPolygon.buffer(-deflateValue)
        if deflatedPolygon.is_empty:
            deflateValue = inf
            break
        if type(deflatedPolygon) is MultiPolygon:
            break
        count += 1

    if shouldPlotResult and not deflatedPolygon.is_empty:
        from exportData.displayShapes import plotPolygons
        plotPolygons([exteriorPolygon, deflatedPolygon])

    return deflateValue
コード例 #3
0
    def getPopulationEnergyPolygonSplit(self, alignment, shouldDrawGraph=False):
        finishingBlocksToAvoid = []
        while True:
            lowestEnergySeamResult = self.getLowestPopulationEnergySeam(alignment=alignment,
                                                                        finishingBlocksToAvoid=finishingBlocksToAvoid)
            if lowestEnergySeamResult is None:
                return SplitType.NoSplit, None
            lowestEnergySeam = lowestEnergySeamResult[0]
            energySeamFinishingBlock = lowestEnergySeamResult[1]
            energySeamStartingEnergy = lowestEnergySeamResult[2]

            seamSplitPolygon = polygonFromMultipleGeometries(geometryList=lowestEnergySeam)
            polygonWithoutSeam = self.geometry.difference(seamSplitPolygon)

            # if the polygon without the seam is empty, that means we have a small enough redistricting group where
            # we need to break it up completely. Because our seams can no longer break up any further.
            if polygonWithoutSeam.is_empty:
                return SplitType.ForceSplitAllBlocks, None

            if type(polygonWithoutSeam) is MultiPolygon:
                seamOnEdge = False
                splitPolygons = list(polygonWithoutSeam)
            else:
                seamOnEdge = True
                splitPolygons = [polygonWithoutSeam, seamSplitPolygon]

            if alignment is Alignment.northSouth:
                aSplitRepresentativeBlockDirection = CardinalDirection.north
                bSplitRepresentativeBlockDirection = CardinalDirection.south
            else:
                aSplitRepresentativeBlockDirection = CardinalDirection.west
                bSplitRepresentativeBlockDirection = CardinalDirection.east

            # Identify which polygon is in which direction
            # Note: Need to make sure we don't select a block in the seam so we supply a list without those blocks
            #   If the seam is completely on the edge though, let's include the seam
            if seamOnEdge:
                borderChildrenRepresentativeCandidates = self.borderChildren
            else:
                borderChildrenRepresentativeCandidates = [child for child in self.borderChildren if
                                                          child not in lowestEnergySeam]

            if len(borderChildrenRepresentativeCandidates) == 0:
                return SplitType.NoSplit, None

            aSplitRepresentativeBlock = mostCardinalOfGeometries(geometryList=borderChildrenRepresentativeCandidates,
                                                                 direction=aSplitRepresentativeBlockDirection)

            bSplitRepresentativeBlock = mostCardinalOfGeometries(geometryList=borderChildrenRepresentativeCandidates,
                                                                 direction=bSplitRepresentativeBlockDirection)

            aSplitPolygon = getPolygonThatContainsGeometry(polygonList=splitPolygons,
                                                           targetGeometry=aSplitRepresentativeBlock,
                                                           useTargetRepresentativePoint=True)
            bSplitPolygon = getPolygonThatContainsGeometry(polygonList=splitPolygons,
                                                           targetGeometry=bSplitRepresentativeBlock,
                                                           useTargetRepresentativePoint=True)
            leftOverPolygons = [geometry for geometry in splitPolygons if
                                geometry is not aSplitPolygon and geometry is not bSplitPolygon]
            if aSplitPolygon is None or bSplitPolygon is None:
                plotPolygons(splitPolygons + [aSplitRepresentativeBlock.geometry, bSplitRepresentativeBlock.geometry])
                saveDataToFileWithDescription(data=self,
                                              censusYear='',
                                              stateName='',
                                              descriptionOfInfo='ErrorCase-AorBSplitIsNone')
                raise RuntimeError('Split a or b not found')

            if aSplitPolygon is bSplitPolygon:
                finishingBlocksToAvoid.append(energySeamFinishingBlock)
                continue

            if len(leftOverPolygons) is not len(splitPolygons) - 2:
                saveDataToFileWithDescription(data=self,
                                              censusYear='',
                                              stateName='',
                                              descriptionOfInfo='ErrorCase-MissingPolygons')
                raise RuntimeError('Missing some polygons for mapping. Split polygons: {0} Left over polygon: {1}'
                                   .format(len(splitPolygons), len(leftOverPolygons)))

            polygonSplits = (aSplitPolygon, bSplitPolygon)

            if shouldDrawGraph:
                plotPolygons(polygonSplits)

            if seamOnEdge:
                return SplitType.SplitIncludedInSeam, polygonSplits, None, energySeamStartingEnergy
            else:
                seamSplitPolygon = polygonFromMultiplePolygons(polygonList=[seamSplitPolygon] + leftOverPolygons)
                return SplitType.NormalSplit, polygonSplits, seamSplitPolygon, energySeamStartingEnergy
コード例 #4
0
                                                          descriptionToWorkWith))

initialDistrict = createDistrictFromRedistrictingGroups(redistrictingGroups=redistrictingGroups)

populationDeviation = populationDeviationFromPercent(overallPercentage=overallPercentageOffIdealAllowed,
                                                     numberOfDistricts=numberOfDistricts,
                                                     totalPopulation=initialDistrict.population)

districts = initialDistrict.splitDistrict(numberOfDistricts=numberOfDistricts,
                                          populationDeviation=populationDeviation,
                                          weightingMethod=WeightingMethod.cardinalDistance,
                                          breakingMethod=BreakingMethod.splitGroupsOnEdge,
                                          shouldMergeIntoFormerRedistrictingGroups=True,
                                          shouldDrawEachStep=False,
                                          shouldRefillEachPass=True,
                                          fastCalculations=False,
                                          showDetailedProgress=False)
saveDataToFileWithDescription(data=districts,
                              censusYear=censusYear,
                              stateName=stateInfo,
                              descriptionOfInfo='{0}-FederalDistricts'.format(descriptionToWorkWith))
saveGeoJSONToDirectoryWithDescription(geographyList=districts,
                                      censusYear=censusYear,
                                      stateName=stateInfo,
                                      descriptionOfInfo='FederalDistrictsGeoJSON')
plotDistricts(districts=districts,
              showPopulationCounts=False,
              showDistrictNeighborConnections=False)
districtPolygons = [district.geometry for district in districts]
plotPolygons(districtPolygons)