def getCityList(self, areaList, label="This includes the cities of", lineLength=66, areaDictName="AreaDictionary", addPeriod = False, forceAlphaSort=False): # Returns a list of cities (from the AreaDictionary) # Access the UGC information for the area(s) if available areaDict = ModuleAccessor.ModuleAccessor().variable(areaDictName, "AreaDictionary") if areaDict is None: return "" cities = [] for areaName in areaList: entry = areaDict[areaName] if entry.has_key("ugcCities"): ct = entry['ugcCities'] for c in ct: if len(c): cities.append(c) if len(cities) and (self.alphabetizeHeaders() == 1 or forceAlphaSort): cities.sort() cityString = self.punctuateList(cities) if len(cityString) == 0: return "" else: if addPeriod: cityString = cityString + '.' return self.endline(label + " " + cityString, lineLength, breakStr=[", "]) + "\n"
def __init__(self): Header.Header.__init__(self) #----------------------------------------------------------------------- # Make a link to the TropicalAreaDictionary # Access the information for the breakpoint area(s) if available self._tropicalAreaDict = \ ModuleAccessor.ModuleAccessor().variable("AreaDictionary", "AreaDictionary") # Then make a cache of sorted hash keys to this dictionary self._tropicalAreaDictKeys = self._tropicalAreaDict.keys() self._tropicalAreaDictKeys.sort(self._sortBreakpoints)
def getCityList(self, areaList, label="This includes the cities of", lineLength=66, areaDictName="AreaDictionary", addPeriod=False, forceAlphaSort=False): # Returns a list of cities (from the AreaDictionary) # Appends an " and " instead of "..." for the last city mentioned. # Access the UGC information for the area(s) if available areaDict = ModuleAccessor.ModuleAccessor().variable( areaDictName, "AreaDictionary") if areaDict is None: return "" cities = [] cityString = "" for areaName in areaList: entry = areaDict[areaName] if entry.has_key("ugcCityString"): ct = entry['ugcCityString'].split('...') for c in ct: if len(c): cities.append(c) if len(cities) and (self.alphabetizeHeaders() == 1 or forceAlphaSort): cities.sort() if len(cities): for c in cities: cityString = cityString + "..." + c cityString = self.replaceLast(cityString, "...", " and ") if len(cityString) == 0: return "" else: if addPeriod: cityString = cityString + '.' return self.endline( label + cityString, lineLength, breakStr=["..."]) + "\n"
def getGeneralAreaList(self, areaList, areaDictName="AreaDictionary"): # Access the UGC information for the area(s) if available areaDict = ModuleAccessor.ModuleAccessor().variable(areaDictName, "AreaDictionary") if areaDict is None: return [] geoAreas = {} for areaName in areaList: entry = areaDict[areaName] if entry.has_key("ugcName"): # Get state state = areaName[0:2] if entry.has_key("fullStateName"): state = entry["fullStateName"] #Special District of Columbia case if state.upper() == "DISTRICT OF COLUMBIA": state = "The District of Columbia" # Get part-of-state information partOfState = "" if entry.has_key("partOfState"): partOfState = entry["partOfState"] # get the county/zone name zoneName = entry["ugcName"] if entry.has_key("locationName"): zoneName = entry["locationName"] #alternative name if entry.has_key("ugcCode"): codeType = entry["ugcCode"][2] if codeType == "Z": nameType = "zone" elif codeType == "C": indCty=entry.get("independentCity", 0) if indCty == 1: nameType = "independent city" elif state == "Louisiana": nameType = "parish" else: nameType = "county" else: codeType == "?" value = (state, partOfState) znt = (zoneName, nameType) if geoAreas.has_key(value): names = geoAreas[value] if znt not in names: names.append(znt) else: geoAreas[value] = [znt] #now sort the zoneName or countyNames for state, partState in geoAreas.keys(): names = geoAreas[(state,partState)] names.sort() #now separate them by land and water #Anything to do with WATERS or other related items go last waters = ['WATERS','LAKE','RIVER'] gaLAND = [] gaWATER = [] for g,pg in geoAreas.keys(): names = geoAreas[(g,pg)] words = g.split(' ') found = 0 for w in waters: if w in words: found = 1 break if found: gaWATER.append((g,pg,names)) else: gaLAND.append((g,pg,names)) #convert the output to a list with land first, then waters geoAreas = [] for g in gaLAND: geoAreas.append(g) for g in gaWATER: geoAreas.append(g) geoAreas.sort() return geoAreas
def makeAreaHeader(self, argDict, areaLabel, issueTime, expireTime, areaDictName, defaultEditAreas, cityDescriptor ="Including the cities of", areaList=None, includeCities=1, includeZoneNames=1, includeIssueTime=1, includeCodes=1, includeVTECString=1, hVTECString=None, accurateCities=False): # Make a UGC area header for the given areaLabel # Determine list of areas (there could be more than one if we are using a combination) if areaDictName is None or areaDictName == "None": return areaLabel + "\n" # If we didn't supply an areaList, # Use combinations file or defaultEditAreas if areaList is None: combinations = argDict["combinations"] if combinations is not None: areaList = self.getCurrentAreaNames(argDict, areaLabel) else: for editArea, label in defaultEditAreas: if label == areaLabel: areaList = [editArea] try: # Remove suffixes if necessary if self._editAreaSuffix is not None: areaList = self.removeSuffixes(areaList, self._editAreaSuffix) except: pass # Access the UGC information for the area(s) if available accessor = ModuleAccessor.ModuleAccessor() areaDict = accessor.variable(areaDictName, "AreaDictionary") ugcCityList = [] if areaDict is None: # create a dummy header codeString = "STZxxx-" nameString = areaLabel cityString = "" else: codeString = "" nameString = "" cityString = "" areaList, ugcList = self.makeUGCList(areaDict, areaList) codeString = self.makeUGCString(ugcList) ugcNameList = [] for areaName in areaList: if areaName in areaDict.keys(): if areaDict.has_key(areaName): entry = areaDict[areaName] else: entry = {} log.error(\ "AreaDictionary missing definition for [" + \ areaName + "].") if entry.has_key('ugcName'): ugcName = entry['ugcName'] else: ugcName = areaName #missing UGCname log.error(\ "AreaDictionary missing ugcName definition for [" + \ areaName + "].") if ugcName not in ugcNameList: ugcNameList.append(ugcName) if entry.has_key("ugcCities"): cities = entry["ugcCities"] for c in cities: if len(c) and c not in ugcCityList: ugcCityList.append(c) else: ugcNameList.append(areaName) log.error("AreaDictionary does not contain " +\ 'ugcName definition for ', areaName) if self.alphabetizeHeaders() == 1: # Alphabetize both lists. ugcNameList.sort() ugcCityList.sort() # Build nameString and cityString strings: for ugcName in ugcNameList: nameString = nameString + ugcName + "-" cityString = self.punctuateList(ugcCityList) # Compute accurate city list if accurateCities and \ len(ugcCityList) > 0 and argDict.has_key("hazards"): ugcCityList, cityString = self.makeAccurateCityList(areaList, \ ugcCityList, argDict) # get the VTEC string from the HazardsTable VTECString = "" VTECRecords = [] if argDict.has_key("hazards") and includeVTECString: hazards = argDict["hazards"] VTECString = hazards.getVTECString(areaList) #must have VTECString, in order to have hVTEC string if hVTECString is not None and len(VTECString) and len(hVTECString): VTECString = VTECString + hVTECString + "\n" # expiration time is dependent upon the passed in expiration time # and the VTEC strings. expireT is seconds since epoch if type(expireTime) is types.IntType or\ type(expireTime) is types.FloatType: expireTime = AbsTime.AbsTime(int(expireTime)) try: if self._fixedExpire == 1: fixed = 1 else: fixed = 0 except: fixed = 0 expireT = self.getExpireTime(issueTime.unixTime(), expireTime.unixTime(), VTECString, fixedExpire = fixed) # format the expiration time expireTimeRange = TimeRange.TimeRange(AbsTime.AbsTime(expireT), AbsTime.AbsTime(expireT+1)) expireTime = self.timeDisplay(expireTimeRange, "", "","%d%H%M", "") codeString = self.endline(codeString + "-" + expireTime + "-", linelength=self._lineLength, breakStr=["-"]) # get this time zone thisTimeZone = os.environ["TZ"] zoneList = [] # check to see if we have any areas outside our time zone for areaName in areaList: if areaName in areaDict.keys(): entry = areaDict[areaName] if not entry.has_key("ugcTimeZone"): #add your site tz if thisTimeZone not in zoneList: zoneList.append(thisTimeZone) continue # skip this entry timeZoneList = entry["ugcTimeZone"] if type(timeZoneList) == types.StringType: # a single value timeZoneList = [timeZoneList] # make it into a list for timeZone in timeZoneList: if timeZone not in zoneList: zoneList.append(timeZone) # if the resulting zoneList is empty, put in our time zone if len(zoneList) == 0: zoneList.append(thisTimeZone) # if the resulting zoneList has our time zone in it, be sure it # is the first one in the list try: index = zoneList.index(thisTimeZone) if index != 0: del zoneList[index] zoneList.insert(0, thisTimeZone) except: pass # now create the time string issueTimeStr = '' timeStrs = [] for timeZone in zoneList: timeStr = self.formatTimeString( issueTime.unixTime(), "%l%M %p %Z %a %b %e %Y", timeZone) timeStr = string.replace(timeStr, " ", " ") timeStr = string.strip(timeStr) if timeStr not in timeStrs: timeStrs.append(timeStr) if len(timeStrs) == 1: issueTimeStr = timeStrs[0] else: issueTimeStr = timeStrs[0] for i in xrange(1, len(timeStrs)): issueTimeStr = issueTimeStr + " /" + timeStrs[i] + "/" try: if self._useRegionLabel == 1: if (areaLabel != ""): nameString = areaLabel except: pass nameString = self.endline(nameString, linelength=self._lineLength,breakStr=["-"]) if cityString != "": numCities = len(ugcCityList) if numCities == 1: def preserveCase(matchobj): orig = matchobj.group(0) repl = 'city' retv = '' for i in range(len(repl)): c = repl[i] if orig[i].isupper(): c = c.upper() retv = retv + c return retv cityDescriptor = re.sub("cities", preserveCase, cityDescriptor, flags=re.IGNORECASE) cityString = self.endline(cityDescriptor + " " + cityString, linelength=self._lineLength, breakStr=[", "]) issueTimeStr = issueTimeStr + "\n\n" try: if self._includeHeader == 0: issueTimeStr = "\n" codeString = "" cityString = "" except: pass if includeCities == 0: cityString = "" if includeZoneNames == 0: nameString = "" if includeIssueTime == 0: issueTimeStr = "" if includeCodes == 0: codeString = "" if includeVTECString == 0: VTECString = "" header = codeString + VTECString + nameString + cityString + issueTimeStr return header
def _separateByTimeZone(self, editAreaGroups, areaDictName, creationTime, effectiveTZ="effectiveTZ"): #takes the list of areas, and based on the time zones breaks #them up to ensure that each grouping using the same time zone. #areaDictName is name of the area dictionary. creationTime is the #run time of the formatter. EffectiveTZ organizes the groups by #the effective time zone, rather than the TZ environment variable. #Typically used for the PFM/AFM. #print("separateByTimeZone: ", editAreaGroups) out = [] #list of editAreaGroups, with edit areas within each group accessor = ModuleAccessor.ModuleAccessor() areaDict = accessor.variable(areaDictName, "AreaDictionary") localTZ = os.environ['TZ'] #current WFO time zone localTZid = time.strftime("%Z", time.localtime(creationTime)) #print("Current WFO tz: ", localTZ) for areas in editAreaGroups: tzDir = {} #key is TZ var (EST5EDT), value is edit areas tzidDir = {} #key is effective TZ (EST), value is edit areas #print("Areas in group: ", areas) for area in areas: #print("processing area: ", area) try: zoneTZ = areaDict[area]['ugcTimeZone'] prevTZ = os.environ['TZ'] os.environ['TZ'] = zoneTZ time.tzset() tzid = time.strftime("%Z", time.localtime(creationTime)) os.environ['TZ'] = prevTZ time.tzset() #print("areadict entry: ", zoneTZ) except: zoneTZ = localTZ tzid = localTZid #print("falling back to WFOtz: ", zoneTZ) self.log.warning( "WARNING: Entry " + area + " missing from AreaDictionary. Using default time zone." ) zones = tzDir.get(zoneTZ, []) zones.append(area) tzDir[zoneTZ] = zones zones = tzidDir.get(tzid, []) zones.append(area) tzidDir[tzid] = zones #print("TZs for areas: ", tzDir) #print("TZids for areas: ", tzidDir) #organize the effective time zones if effectiveTZ == "effectiveTZ": tzDict = tzidDir elif effectiveTZ == "actualTZ": tzDict = tzDir else: self.log.error("Invalid effectiveTZ for separateByTZ() " + effectiveTZ) return editAreaGroups keys = tzDict.keys() keys.sort() for key in keys: out.append(tzDict[key]) #print("After TZ separate: ", out) return out
def __getRunTimeVariables(self, fcstName, forecastDef, fcstType, module, argDict): # Input variables can come from various sources: # varDict from command line # command line switch e.g. -l language (will be in argDict) # definition section of product # We must check all three in that order. varDict = argDict["varDict"] #print("varDict", varDict) for item, default in [ ("language", "english"), ("appendFile", None), ("lineLength", 69), # no command line option ("timePeriod", 3), ]: try: # Try the varDict #print("trying varDict", item) argDict[item] = varDict[item] #print("got it in varDict") except: try: # Try argDict i.e. from command line switch # If so, argDict is already set #print("trying argDict", item) argValue = argDict[item] #print("got it in argDict", argValue) except: argValue = None # Try #print("getting from definition", item) if argValue is None: argDict[item] = self.__ut.set(forecastDef, item, default) #print("value from definition", argDict[item]) # These need to be integers for item in ["lineLength", "timePeriod"]: if argDict[item] is not None: argDict[item] = int(argDict[item]) # Edit Areas and Time Ranges # # Set up these argDict values: # editAreas -- list of (refData, label) pairs # timeRanges -- list of named ranges # rawRanges -- list of (rawRange, rangeName) pairs # # As we eventually loop through the product, these values will be set: # editArea -- current edit area pair # timeRange -- current raw time range # issueTime -- first raw time range # timeRangeName -- current time range name (if available) # combinations -- list of (editAreaList, comboLabel) tuples # where editAreaList is the list of edit areas composing # the combination # Set up Edit Areas # May be from these sources: # "AreaLabel" # varDict from command line -- list of names # command line as named reference areas # defaultEditAreas # list of (name, label) pairs # "LatLon" # OR list of ((lat,lon,dimension), label) # "Combinations" # OR A Combinations file # We may have had edit areas entered from the command line # or from the Interfaces "generateForecast" command # If so, argDict["editAreas"] will be a list of either # (name, label) or (refData, label) pairs editAreaType = "AreaLabel" # We may have had edit areas entered from the command line # If so, argDict["editAreas"] will be a list of either # (name, label) or (refData, label) pairs if len(argDict["editAreas"]) == 0: dfEditAreas = self.__ut.set(forecastDef, "defaultEditAreas", []) try: # Try the varDict chosenAreas = varDict["Choose Edit Areas"] # Turn the list of chosen areas into (name, label) pairs # using the defaultEditAreas list dfEditAreas = self.__pairAreaWithLabel(chosenAreas, dfEditAreas) except: pass # Set up edit areas as ReferenceData's for AreaLabel and LatLon areas if type(dfEditAreas) == types.StringType: editAreaType = "Combinations" # Get edit areas from file with format: # Combinations = [ # ([editArea1, editArea2,...],label) # ... # ] # For example: # Combinations = [ # (["Zones48", "Zones49", "Zones50"],"/48/49/50"), # (["Zones37","Zones38"], "/37/38"),"/37/38"), # (["Zones57","Zones58","Zones59"],"57/58/59") # ] comboName = dfEditAreas for retryCount in xrange(MAX_TRIES): accessor = ModuleAccessor.ModuleAccessor() dfEditAreas = accessor.variable(comboName, "Combinations") if dfEditAreas is None: if sys.modules.has_key(comboName): comboMod = sys.modules[comboName] if comboMod.__file__.endswith(".pyo"): os.remove(comboMod.__file__) comboMod = None del sys.modules[comboName] # if not last try, log and try again if retryCount < MAX_TRIES - 1: # log but don't pop up self.log.error( "Error loading combinations file: %s, retrying", comboName) else: return "COMBINATION FILE NOT FOUND: " + \ self.__ut.set(forecastDef, "defaultEditAreas", []) else: break elif len(dfEditAreas) > 0: refDataList = [] tempRefData = [] for area, label in dfEditAreas: if type(area) is types.TupleType: # Create a referenceData given lat, lon, dim refData = self.__createArea(area, argDict) tempRefData.append(refData) else: # Get named Reference Data refId = ReferenceID(area) refData = self.getEditArea(area, argDict) if refData is None: return "EDIT AREA NOT FOUND: " + str(refId) refDataList.append((refData, label)) argDict["editAreas"] = refDataList storeReferenceData(self.dataMgr.getRefManager(), tempRefData) # Set up HazardsTable # Product must be: # --Type "smart" # --Have an "filterMethod" method if fcstType == "smart": product = module.TextProduct() # Test Code: Uncomment to test #allowedHazards = product.allowedHazards() #filterMethod = product.filterMethod #print("allowedHazards", allowedHazards) try: allowedHazards = product.allowedHazards() filterMethod = product.filterMethod except: allowedHazards = None if allowedHazards is not None and allowedHazards != []: # Set up editAreas as a list of combinations # Cases: # lat/lon or (area, label) pairs -- call HazardsTable, # but the edit areas will not change # Combinations -- call HazardsTable and check for changed combinations # Set up edit areas as list of lists editAreas = [] for area, label in dfEditAreas: if type(area) is types.ListType: editAreas.append(area) elif type(area) is types.TupleType: #LatLon editAreas.append([self.__getLatLonAreaName(area)]) else: editAreas.append([area]) # if Definition['separateByTimeZone'] set to "effectiveTZ" # or "actualTZ", change the set of edit areas to ensure # that time zones are same in each grouping. separateByTZ = product.Definition.get('separateByTimeZone', None) if separateByTZ is not None: areaDictName = product.Definition.get( 'areaDictionary', "AreaDictionary") editAreas = self._separateByTimeZone( editAreas, areaDictName, argDict['creationTime'], effectiveTZ=separateByTZ) accurateCities = product.Definition.get('accurateCities', 0) cityRefData = [] if accurateCities: cityLocationName = product.Definition.get( 'cityLocation', "CityLocation") accessor = ModuleAccessor.ModuleAccessor() citydict = accessor.variable(cityLocationName, "CityLocation") cityEAs = [] if citydict is None: msg = "CityLocation dictionary module was not found for"\ " city location:" self.log.error(msg + repr(cityLocationName)) else: for ea in editAreas: for ean in ea: if ean not in citydict: msg = "CityLocation dictionary does not "\ "contain entry for edit area: " self.log.error(msg + repr(ean)) continue for city, llrec in citydict[ean].iteritems(): # Create a referenceData given lat, lon, dim area = (llrec[0], llrec[1], 0) refData = self.__createArea(area, argDict) cityEAs.append(refData) cityRefData.append((refData, city)) # Store temporary reference data in the server storeReferenceData(self.dataMgr.getRefManager(), cityEAs) # Get Product ID and other info for HazardsTable pil = self.__ut.set(forecastDef, "pil", None) stationID4 = product.Definition['fullStationID'] productCategory = pil[0:3] #part of the pil sampleThreshold = product.Definition.get(\ "hazardSamplingThreshold", (10, None)) # Process the hazards import HazardsTable hazards = HazardsTable.HazardsTable( argDict["ifpClient"], editAreas, productCategory, filterMethod, argDict["databaseID"], stationID4, argDict["vtecActiveTable"], argDict["vtecMode"], sampleThreshold, creationTime=argDict["creationTime"], dataMgr=self.dataMgr, accurateCities=accurateCities, cityEditAreas=cityRefData) # Store hazards object for later use argDict["hazards"] = hazards # Get revised combinations if editAreaType == "Combinations": reorganizeCombos = product.Definition.get( "reorganizeCombinations", 1) if reorganizeCombos: hazardAreas = hazards.getHazardAreaCombinations() # Add a bogus label newCombos = [] for combo in hazardAreas: newCombos.append((combo, "")) # Re-assign new combinations dfEditAreas = newCombos # Set up Combinations as ReferenceDatas if editAreaType == "Combinations": argDict["editAreas"], dfEditAreas = self.getCombinations( dfEditAreas, argDict) argDict["combinations"] = dfEditAreas # Set up Time Ranges # May be from these sources: # varDict from command line # defaultTimeRanges # command line as named time ranges # command line as start and end times OR # from argDict already set up by Interfaces::generateProduct # In these cases "useRawTR" will be set to 1 if len(argDict["timeRanges"]) > 0: # Use named time ranges from command line dfRanges = argDict["timeRanges"] else: try: # Try the varDict dfRanges = varDict["Choose Time Ranges"] except: dfRanges = self.__ut.set(forecastDef, "defaultRanges", []) argDict["timeRanges"] = dfRanges rawRanges = [] argDict["rawRanges"] = rawRanges if argDict["useRawTR"] == 1: tr = argDict["timeRange"] try: trName = argDict["timeRangeName"] except: trName = "" if tr is not None: rawRanges.append((tr, trName)) elif len(dfRanges) == 0: pass else: import TimeRangeUtils forecast = TimeRangeUtils.TimeRangeUtils() for rangeName in dfRanges: rawRange = forecast.getTimeRange(rangeName, argDict) rawRanges.append((rawRange, rangeName)) argDict["rawRanges"] = rawRanges #print("rawRanges", rawRanges) # Row Label areaType = self.__ut.set(forecastDef, "areaType", "") rowVariable = self.__ut.set(forecastDef, "rowVariable", "EditArea") if rowVariable == "EditArea": rowLabel = areaType elif rowVariable == "WeatherElement": rowLabel = "Weather Element" else: rowLabel = "Time Period" argDict["heading"] = rowLabel
def _makeHazardBlock(self, fcst, argDict): fcst = fcst + "." + self._wfoSiteID + \ " WATCHES/WARNINGS/ADVISORIES...\n" accessor = ModuleAccessor.ModuleAccessor() areaDict = accessor.variable(self._areaDictionary, "AreaDictionary") # get combinations file used, which contains extra info which will # tell us which zones are marine, firewx and public combo = self._defaultEditAreas fireWxPhenSig = [("FW", "W"), ("FW", "A")] fireWxZones = [] otherZones = [] if type(combo) is types.StringType: try: m = __import__(combo) for map in m.EASourceMap.keys(): if map.find("FireWx") != -1: fireWxZones = m.EASourceMap[map] else: for idz in m.EASourceMap[map]: if idz not in otherZones: otherZones.append(idz) except: otherZones = None marine = self.marineNameDict() # # Get every hazard and hazard combination in effect, separate them # into records by state # hazardsRaw = argDict['hazards'].rawAnalyzedTable() hazards = self._combineHazardRecords(hazardsRaw, argDict) stateDict = {} for h in hazards: #determine the states in this record sd = {} ids = h['id'] for id in ids: stateid = id[0:2] if sd.has_key(stateid): locs = sd[stateid] locs.append(id) sd[stateid] = locs else: sd[stateid] = [id] #add the record to the appropriate "state" in stateDict for state in sd.keys(): hcopy = copy.deepcopy(h) if stateDict.has_key(state): recs = stateDict[state] hcopy['id'] = sd[state] recs.append(hcopy) stateDict[state] = recs else: hcopy['id'] = sd[state] stateDict[state] = [hcopy] # # For every state we are responsible for, check for hazards # for eachState in self._state_IDs: if stateDict.has_key(eachState): stateHazardList = stateDict[eachState] else: stateHazardList = [] # add the state identifier (only if multiple states) if len(self._state_IDs) > 1: #marine zone if eachState in marine.keys(): fcst = fcst + marine[eachState] + "..." else: fcst = fcst + eachState + "..." # If no hazards are found, append the null phrase if len(stateHazardList) == 0: fcst = fcst + self._WWA_Nil + "\n" continue # If hazards are found, then build the hazard phrases for i in xrange(len(stateHazardList)): eachHazard = stateHazardList[i] # special check code for firewx if (eachHazard['phen'], eachHazard['sig']) in fireWxPhenSig: firezones = [] for id in eachHazard['id']: if id in fireWxZones and id not in firezones: firezones.append(id) eachHazard['id'] = firezones #eliminated public stateHazardList[i] = eachHazard else: otherzones = [] for id in eachHazard['id']: if (otherZones is None or id in otherZones) and id not in otherzones: otherzones.append(id) eachHazard['id'] = otherzones #eliminated firewx stateHazardList[i] = eachHazard # hazard name hazName = self.hazardName(eachHazard['hdln'], argDict, False) # timing phrase timing = self.getTimingPhrase(eachHazard, argDict['creationTime']) # ids ids = eachHazard['id'] if len(ids) == 0: continue #skip hazard string if no zones if self._useZoneNames == 1: zoneNames = [] for id in ids: zoneNames.append(areaDict[id]['ugcName']) ids = zoneNames ids.sort() idString = "-".join(ids) if self._useZoneNames == 0 and self._abbreviateUGCs == 1: idString = self.makeUGCString(ids) # hazard phrase phrase = hazName + ' ' + timing + ' for ' + idString + '.' # Indent if there is a state list associated if len(self._state_IDs) > 1: phrase = self.indentText(phrase, indentFirstString='', indentNextString=' ', maxWidth=self._lineLength, breakStrings=[" ", "-"]) else: phrase = self.indentText(phrase, indentFirstString='', indentNextString='', maxWidth=self._lineLength, breakStrings=[" ", "-"]) # Apply the hazard phrases if len(self._state_IDs) > 1: #don't indent 1st one if i == 0: fcst = fcst + phrase + '\n' #ident the remainder else: fcst = fcst + " " + phrase + '\n' else: fcst = fcst + phrase + '\n' #never ident - only 1 state fcst = fcst + "&&\n\n" return fcst
def _getLocationsList(self, areaDictionary, argDict, seg): # Access the UGC information for the area(s) if available accessor = ModuleAccessor.ModuleAccessor() areaDict = accessor.variable(areaDictionary, "AreaDictionary") areaList = argDict['segmentAreas'] ugcList = [] zoneNameList = [] stateList = [] nameString = "" # Cycle through each zone in this segment for areaName in areaList: if areaName in areaDict.keys(): if areaDict.has_key(areaName): entry = areaDict[areaName] else: entry = {} LogStream.logProblem(\ "AreaDictionary missing definition for [" + \ areaName + "].") if entry.has_key('ugcName'): ugcName = entry['ugcName'] else: ugcName = areaName #missing UGCname LogStream.logProblem(\ "AreaDictionary missing ugcName definition for [" + \ areaName + "].") if entry.has_key('ugcCode'): ugcCode = entry['ugcCode'] else: ugcCode = areaName #missing UGCcode LogStream.logProblem(\ "AreaDictionary missing ugcCode definition for [" + \ areaName + "].") if entry.has_key('fullStateName'): ugcState = entry['fullStateName'] else: ugcState = areaName #missing fullStateName LogStream.logEvent(\ "AreaDictionary missing fullStateName definition for [" + \ areaName + "].") if ugcName not in ugcList: ugcList.append((ugcState, ugcName, ugcCode[3:])) if ugcState not in stateList: stateList.append(ugcState) ### sort ugclist by state ugcList.sort() stateList.sort() ### check the length of stateList for multiple states if len(stateList) <= 1: ### only one state ### include state name if self._includeStateName == 1: nameString += "In " + stateList[0] + "..." ### sort based on zone number ugcList = sorted(ugcList, key=lambda ugc: ugc[2]) if self._noNameInBullet == 0: ### include zone names and numbers zoneList = [ "Fire weather zone " + ugc[2] + " " + ugc[1] for ugc in ugcList ] else: ### include zone numbers if len(ugcList) > 1: nameString += "Fire weather zones " else: nameString += "Fire weather zone " zoneList = [ugc[2] for ugc in ugcList] nameString += self.punctuateList(zoneList) + "." else: ### more than one state for state in stateList: ### include state name if self._includeStateName == 1: nameString = nameString + "In " + state + "..." newList = [] ### split up ugcList for each state. for st, name, num in ugcList: if st == state: newList.append((num, name)) ### sort for zone numbers newList.sort() if self._noNameInBullet == 0: ### include zone names zoneList = [ "Fire weather zone " + ugc[0] + " " + ugc[1] for ugc in newList ] else: ### don't include zone names if len(newList) > 1: nameString += "Fire weather zones " else: nameString += "Fire weather zone " zoneList = [ugc[0] for ugc in newList] nameString += self.punctuateList(zoneList) + "." ### get rid of any spaces in the ellipses nameString = nameString.replace("... ", "...") nameString = nameString.replace(" ...", "...") return nameString
def _getFilteredAreaList(self, areaList, areaDictName="AreaDictionary", mode="COUNTY"): #returns list of sorted tuples: # [(state, partOfState, partOfState State, zonename)] #mode='COUNTY','ZONE','CITY' # Access the UGC information for the area(s) if available areaDict = ModuleAccessor.ModuleAccessor().variable( areaDictName, "AreaDictionary") if areaDict is None: return [] # sort by zone name if mode == "ZONE": areaList.sort() # Make a list of (state, partOfStateAndState, county) tuples countyList = [] for areaName in areaList: if areaDict.has_key(areaName): entry = areaDict[areaName] else: entry = {} LogStream.logProblem(\ "AreaDictionary missing definition for [" + areaName + "].") if mode == "COUNTY": if len(areaName) == 6 and areaName[2] != "C": #not ssCnnn continue #not a county fips if entry.has_key("independentCity") and \ entry["independentCity"] == 1: continue #independent city, when in county mode elif mode == "CITY": if len(areaName) == 6 and areaName[2] != "C": #not ssCnnn continue #not a county/city fips if not entry.has_key("independentCity") or \ entry["independentCity"] == 0: continue #not independent city, when in city mode elif mode == "ZONE": if len(areaName) == 6 and areaName[2] != "Z": #not ssZnnn continue #not a zone code else: raise Exception, "Illegal mode specified " + mode if entry.has_key("ugcName") and len(entry['ugcName']): # Get fullStateName state = areaName[0:2] if entry.has_key("fullStateName") and \ len(entry['fullStateName']): state = entry["fullStateName"] else: state = "<fullStateName for " + state + " missing>" LogStream.logProblem("AreaDictionary does not contain " +\ 'fullStateName definition for ', areaName) # Get part-of-state information with state (not for Zones) if mode == "ZONE": #marine partOfState = "" else: if entry.has_key("partOfState") and \ len(entry['partOfState']): partOfState = entry["partOfState"] + ' ' + state else: partOfState = "<partOfState> " + state LogStream.logProblem(\ "AreaDictionary does not contain " +\ 'partOfState definition for ', areaName) # Get county name county = entry["ugcName"] # Eliminate the name County and others, if in the name if mode == "COUNTY": val = ['County', 'Counties', 'Parish', 'Parishes'] for v in val: county = county.replace(" " + v, "") countyList.append((state, partOfState, county)) #missing ugcName else: countyList.append(("<ugcName>", "<ugcName>", areaName)) LogStream.logProblem("AreaDictionary does not contain " +\ 'ugcName definition for ', areaName) # Sort by state, part of state, then county if mode != "ZONE": countyList.sort() #state, partOfState, county return countyList