def readOutputProfile(fname):
    fp = open(fname, 'r')
    profTable = {}
    ignColor = (107, 165, 210)
    unknownColor = (255, 0, 255)
    try:
        for line in fp:
            if ((line[0] != '#') and (not (line.isspace()))):
                rmatch = re.match(r"""\s*([^:]+)\s*:\s*\(\s*([0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*)\s*\)""", line)
                if rmatch:
                    oColor = rmatch.group(2)
                    rgbVals = oColor.split(',')
                    rval = int(rgbVals[0].strip())
                    gval = int(rgbVals[1].strip())
                    bval = int(rgbVals[2].strip())
                    key = rmatch.group(1).strip()
                    if ((rval < 0) or (rval > 255) or (gval < 0) or (gval > 255) or (bval < 0) or (bval > 255)):
                        raise SKCCError('Invalid RGB color in output profile: ' + str((rval, gval, bval)))
                    if (key == 'Ignored') or (key == 'Ocean'):
                        ignColor = (rval, gval, bval)
                    if (key == 'Unknown'):
                        unknownColor = (rval, gval, bval)
                    if (key in profTable):
                        print('Warning: Duplicate entries for key | ' + kClass + ' | in output profile')
                    profTable[key] = (rval, gval, bval)
                else:
                    raise SKCCError('Invalid line in output profile: ' + line)
    finally:
        fp.close()
    return OutputProfile(profTable, ignColor, unknownColor)
def readInputProfile(fname):
    fp = open(fname, 'r')
    profTable = {}
    ignoredColors = []
    defaultVal = None
    try:
        for line in fp:
            if ((line[0] != '#') and (not (line.isspace()))):
                rmatch = re.match(
                    r"""[^:]*:\s*\((Default|[0-9]+,\s*[0-9]+,\s*[0-9]+\s*)\)\s*:\s*(-?[0-9.]*X?O?)""",
                    line)
                if rmatch:
                    iColor = rmatch.group(1)
                    if (iColor == 'Default'):
                        iValue = rmatch.group(2)
                        if (not (defaultVal is None)):
                            print(
                                'Warning: Duplicate default value in input profile: '
                                + iValue)
                        if ((iValue == 'X') or (iValue == 'O')):
                            defaultVal = 'X'
                        else:
                            defaultVal = float(iValue)
                    else:
                        rgbVals = iColor.split(',')
                        rval = int(rgbVals[0].strip())
                        gval = int(rgbVals[1].strip())
                        bval = int(rgbVals[2].strip())
                        if ((rval < 0) or (rval > 255) or (gval < 0)
                                or (gval > 255) or (bval < 0) or (bval > 255)):
                            raise SKCCError(
                                'Invalid RGB color in input profile: ' +
                                str((rval, gval, bval)))
                        iValue = rmatch.group(2)
                        if ((rval, gval, bval) in profTable):
                            print(
                                'Warning: Duplicate color in input profile: ' +
                                str((rval, gval, bval)))
                        if ((iValue == 'X') or (iValue == 'O')):
                            ignoredColors.append((rval, gval, bval))
                        else:
                            ival = float(iValue)
                            profTable[(rval, gval, bval)] = ival
                else:
                    raise SKCCError('Invalid line in input profile: ' + line)
    finally:
        fp.close()
    return InputProfile(profTable, ignoredColors, default=defaultVal)
Esempio n. 3
0
def getPrecipitationPattern(tType, tempTuple, precTuple, annualPrecip):
    if (tType == 'A'):
        if ((precTuple[0] > 60) and (precTuple[1] > 60)):
            return 'f'
        else:
            wThresh = 100 - (annualPrecip / 25.0)
            dryPrecip = min(precTuple[0], precTuple[1])
            if (dryPrecip >= wThresh):
                return 'm'
            elif (precTuple[1] < 60):
                return 'w'
            else:
                return 's'
    elif ((tType == 'C') or (tType == 'D')):
        if (precTuple[1] < (precTuple[0] * 0.1)):
            return 'w'
        elif ((precTuple[0] < (precTuple[1] * 0.33)) and (precTuple[0] < 40)):
            return 's'
        else:
            return 'f'
    elif (tType == 'E'):
        if (max(tempTuple[0], tempTuple[1]) < 0):
            return 'F'
        else:
            return 'T'
    else:
        raise SKCCError(
            'Invalid climate category for getPrecipitationPattern; should never happen'
        )
Esempio n. 4
0
def makeRGBConversion(img1, img2, img3, img4):
    bands = [
        img1.getbands(),
        img2.getbands(),
        img3.getbands(),
        img4.getbands()
    ]
    bandIds = []
    for bandList in bands:
        if not ('R' in bandList):
            raise SKCCError(
                'No red color channel in one or more input images.')
        elif not ('G' in bandList):
            raise SKCCError(
                'No green color channel in one or more input images.')
        elif not ('B' in bandList):
            raise SKCCError(
                'No blue color channel in one or more input images.')
        else:
            bandIds.append((bandList.index('R'), bandList.index('G'),
                            bandList.index('B')))
    if (bandList[0] == ('R', 'G', 'B')) and (bandList[1] == (
            'R', 'G', 'B')) and (bandList[2]
                                 == ('R', 'G', 'B')) and (bandList[3]
                                                          == ('R', 'G', 'B')):
        # Special case to improve performance if input is all RGB images with no channels
        def retRGB(pxTuple):
            return pxTuple

        return retRGB
    else:

        def getRGB(pxTuple):
            return ((pxTuple[0][bandIds[0][0]], pxTuple[0][bandIds[0][1]],
                     pxTuple[0][bandIds[0][2]]),
                    (pxTuple[1][bandIds[1][0]], pxTuple[1][bandIds[1][1]],
                     pxTuple[1][bandIds[1][2]]),
                    (pxTuple[2][bandIds[2][0]], pxTuple[2][bandIds[2][1]],
                     pxTuple[2][bandIds[2][2]]), (pxTuple[3][bandIds[3][0]],
                                                  pxTuple[3][bandIds[3][1]],
                                                  pxTuple[3][bandIds[3][2]]))

        return getRGB
 def getValue(self, rgbColor):
     if not (rgbColor in self.colorTable):
         if self.defaultValue is None:
             raise SKCCError(
                 'Invalid color in input data (did not match input profile): ('
                 + str(rgbColor[0]) + ', ' + str(rgbColor[1]) + ', ' +
                 str(rgbColor[2]) + ')')
         else:
             return self.defaultValue
     else:
         return self.colorTable[rgbColor]
Esempio n. 6
0
def readAndValidateHoldridgeOutputProfile(fname):
    profile = readOutputProfile(fname)

    for zone in profile.colorTable:
        if not (zone == 'Ocean'):
            if (not (zone in hColorTableDefault)):
                raise SKCCError(
                    'Invalid Holdridge category in output profile: ' + zone)
        else:
            if profile.ignoredColor != defaultOceanColor:
                profile.ignoredColor = profile.colorTable[zone]
    if ('Ocean' in profile.colorTable):
        profile.colorTable.pop('Ocean', None)
    return profile
Esempio n. 7
0
def readAndValidateKoppenOutputProfile(fname):
    profile = readOutputProfile(fname)

    for climate in profile.colorTable:
        if not (climate == 'Ocean'):
            if (not (climate in kColorTableDefault)):
                raise SKCCError(
                    'Invalid Köppen-Geiger class in output profile: ' +
                    climate)
        else:
            if profile.ignoredColor != defaultOceanColor:
                profile.ignoredColor = profile.colorTable[climate]
    if ('Ocean' in profile.colorTable):
        profile.colorTable.pop(climate, None)
    return profile
Esempio n. 8
0
def getClimateColor(pxTuple, tempProfile, precProfile, outProfile,
                    isNorthernHemis):
    # pxTuple contains a tuple of four pixels, for (temp1, temp2, precip1, precip2).
    # If this pixel in any input has the ocean color we treat this pixel as ocean and ignore it.
    if (tempProfile.isIgnored(pxTuple[0]) or tempProfile.isIgnored(pxTuple[1])
            or precProfile.isIgnored(pxTuple[2])
            or precProfile.isIgnored(pxTuple[3])):
        return outProfile.ignoredColor
    else:
        tempTuple, precTuple = convertPixelData(pxTuple, tempProfile,
                                                precProfile, isNorthernHemis)
        #Temptuple is (avg. for summer, avg. for winter)
        #precTuple is (category for summer, category for winter)
        tType = getTemperatureType(tempTuple)
        pType = 'f'  #Placeholder value

        annualPrecip = 0.0  # Placeholder value
        #Check for aridity (polar climate category exempted)
        if (tType != 'E'):
            evaporation, annualPrecip = getEvaEstimate(tempTuple, precTuple)
            if (annualPrecip < (evaporation / 2.0)):
                tType = 'B'
                pType = 'W'
            elif (annualPrecip < evaporation):
                tType = 'B'
                pType = 'S'

        if (tType != 'B'):
            pType = getPrecipitationPattern(tType, tempTuple, precTuple,
                                            annualPrecip)

        stType = getSeasonalPattern(tType, tempTuple)

        climateCode = tType + pType
        if (stType != 'x'):
            climateCode = climateCode + stType
        if (climateCode in outProfile.colorTable):
            return outProfile.colorTable[climateCode]
        else:
            raise SKCCError(
                'Invalid Köppen-Geiger climate class (should never happen): ' +
                climateCode)
Esempio n. 9
0
def validateMode(md):
    if md in modes:
        return md
    else:
        raise SKCCError('Invalid mode specified: ' + mode)
Esempio n. 10
0
def outputToFile(filename, img):
    try:
        img.save(filename)
    except:
        raise SKCCError('Could not write to file' + filename)
Esempio n. 11
0
def optErr():
    raise SKCCError(
        'Invalid options. Use the \'-h\' or \'--help\' options for usage information.'
    )
Esempio n. 12
0
                    precProfile = readInputProfile(a[1])
            if a[0] == '-k' or a[0] == '--outprof':
                if a[1] == '':
                    optErr()
                else:
                    # Output profiles differ by mode
                    if (mode == 'koppen'):
                        outProfile = readAndValidateKoppenOutputProfile(a[1])
                    elif (mode == 'holdridge'):
                        outProfile = readAndValidateHoldridgeOutputProfile(
                            a[1])
            if a[0] == '-s' or a[0] == '--quiet':
                quiet = True
        if ((not tempFileNameNS) or (not tempFileNameNW)
                or (not precFileNameNS) or (not precFileNameNW)):
            raise SKCCError(
                'One or more required input data files were not specified.')
        if (not outfileName):
            raise SKCCError('No output filename specified.')

        # Generate the output.
        outputToFile(
            outfileName,
            buildOutput(tempFileNameNS, tempFileNameNW, precFileNameNS,
                        precFileNameNW, tempProfile, precProfile, outProfile,
                        mode))
        if not quiet:
            stopTime = time.time()
            timeDiffRounded = format(stopTime - startTime, '.2f')
            print('Output climate map to ' + outfileName + ' (' +
                  timeDiffRounded + 's).')
    except Exception as e: