awips2/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/createAreaDictionary.py
Steve Harris 61224dec54 12.11.1-10 baseline
Former-commit-id: 63dddc5f5f [formerly e845c605e6] [formerly 0ba69044a2 [formerly 9dd41e6322bad3e7dced1a32867d9a7f886d70cf]]
Former-commit-id: 0ba69044a2
Former-commit-id: cc21977c35
2012-10-24 15:13:57 -05:00

389 lines
14 KiB
Python

##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
import os, string, copy
import tempfile, stat
import LogStream, pprint
from fips2cities import *
from zones2cities import *
#
# Creates area dictionary specific to a site. Somewhat ported from AWIPS-I.
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/08/10 #1209 randerso Initial Creation.
# 10/19/12 #1091 dgilling Support localMaps.py.
#
#
#
CityLocationDict = {}
# obtain real time zone string from shapefile TIME_ZONE variable
def getRealTimeZone(tzstring):
d = {'M':"MST7MDT",'m':"MST7",'V':'America/Puerto_Rico',
'E':"EST5EDT",'e':"EST5",
'C':"CST6CDT",'P':"PST8PDT",'A':"America/Anchorage",
'H':"Pacific/Honolulu",'G':"Pacific/Guam",
'J':"Pacific/Palu", 'K': "Pacific/Wake", 'F': "Pacific/Ponape"}
tzones = []
for tz in tzstring:
if d.has_key(tz):
tzones.append(d[tz])
if len(tzones) > 1:
return tzones
elif len(tzones) == 1:
return tzones[0]
else:
LogStream.logProblem("No time zone information decodable: ", tzstring)
return None
# sorts the cities by decending population
def citysort(c1, c2):
if c1[1] is None and c2[1] is None:
return 0
elif c1[1] is None:
return 1
elif c2[1] is None:
return -1
elif c1[1] < c2[1]:
return 1
elif c1[1] > c2[1]:
return -1
else:
return 0
# Creates the city string part of the area dictionary, based on population
def makeCityString(dictRecord):
if dictRecord.has_key("cities"):
cities = copy.deepcopy(dictRecord["cities"])
if len(cities) == 0:
return None
cities.sort(citysort)
locs = {}
s = ""
count = 0
maxPop = cities[0][1] #population of largest city
for x in xrange(len(cities)):
#limit small cities to 25% of the large city population
if maxPop is not None and cities[x][1] is not None and \
cities[x][1] * 4 < maxPop:
break
elif maxPop is not None and cities[x][1] is None:
break
s = s + "..." + cities[x][0]
# save data to cifyLocation dictionary
locs[cities[x][0]] = tuple(map(float, cities[x][2:4]))
#max of 6 cities in the list
count = count + 1
if count > 6:
break
return s, locs
# handle marine states
def checkMarineState(ugcCode):
#returns None if unknown, description if known
areas = {'AM': 'ATLANTIC COASTAL WATERS', 'GM': 'GULF OF MEXICO',
'LE': 'LAKE ERIE', 'LO': 'LAKE ONTARIO', 'LH': 'LAKE HURON',
'SC': 'LAKE ST CLAIR', 'LM': 'LAKE MICHIGAN', 'LS': 'LAKE SUPERIOR',
'PZ': 'PACIFIC COASTAL WATERS', 'PK': 'ALASKAN COASTAL WATERS',
'PH': 'HAWAIIAN COASTAL WATERS', 'PM': 'MARIANAS WATERS',
'AN': 'ATLANTIC COASTAL WATERS', 'PS': 'AMERICAN SAMOA COASTAL WATERS',
'SL': 'ST LAWRENCE RIVER'}
area = ugcCode[0:2]
return areas.get(area, None)
# Utility to create the area dictionary, based on the map background data
def createAreaDictionary(outputDir, mapDict):
LogStream.logEvent("Generating AreaDictionary")
areadict = {}
mapIter = mapDict.entrySet().iterator()
while mapIter.hasNext():
entry = mapIter.next()
ean = str(entry.getKey())
att = entry.getValue()
if len(ean):
try:
d = {}
if att.containsKey('zone') and att.containsKey('state'):
d['ugcCode'] = str(att.get('state')) + "Z" + str(att.get('zone'))
elif att.containsKey('id'):
d['ugcCode'] = str(att.get('id'))
elif att.containsKey('fips') and att.containsKey('state') and \
att.containsKey('countyname'):
d['ugcCode'] = str(att.get('state')) + "C" + str(att.get('fips'))[-3:]
d['ugcName'] = string.strip(str(att.get('countyname')))
else:
continue
if att.containsKey('state'):
d["stateAbbr"] = str(att.get('state'))
if att.containsKey('name'):
d["ugcName"] = string.strip(str(att.get('name')))
if att.containsKey('time_zone'):
tzvalue = getRealTimeZone(str(att.get('time_zone')))
if tzvalue is not None:
d["ugcTimeZone"] = tzvalue
if zonedata.has_key(d['ugcCode']):
cityDict = zonedata[d['ugcCode']]
elif fipsdata.has_key(d['ugcCode']):
cityDict = fipsdata[d['ugcCode']]
else:
cityDict = None
if cityDict:
cityString = makeCityString(cityDict)
if cityString is not None:
cityString, locs = cityString
if len(cityString):
d["ugcCityString"] = cityString
CityLocationDict[ean] = locs
# partOfState codes
if zonedata.has_key(d['ugcCode']):
if zonedata[d['ugcCode']].has_key('partOfState'):
d["partOfState"] = \
zonedata[d['ugcCode']]['partOfState']
elif fipsdata.has_key(d['ugcCode']):
if fipsdata[d['ugcCode']].has_key('partOfState'):
d["partOfState"] = \
fipsdata[d['ugcCode']]['partOfState']
# full state name
if zonedata.has_key(d['ugcCode']):
if zonedata[d['ugcCode']].has_key('fullStateName'):
d["fullStateName"] = \
zonedata[d['ugcCode']]['fullStateName']
elif fipsdata.has_key(d['ugcCode']):
if fipsdata[d['ugcCode']].has_key('fullStateName'):
d["fullStateName"] = \
fipsdata[d['ugcCode']]['fullStateName']
else:
marineState = checkMarineState(d['ugcCode'])
if marineState is not None:
d['fullStateName'] = marineState
if areadict.has_key(ean) and d != areadict[ean]:
LogStream.logDiag("Mismatch of definitions in " +\
"AreaDictionary creation. EditAreaName=", ean,
"AreaDict=\n", areadict[ean], "\nIgnored=\n", d)
else:
areadict[ean] = d
except:
LogStream.logProblem("Problem with ", ean, LogStream.exc())
s = """
# ----------------------------------------------------------------------------
# This software is in the public domain, furnished "as is", without technical
# support, and with no warranty, express or implied, as to its usefulness for
# any purpose.
#
# AreaDictionary
# AreaDictionary file
#
# Author: GFE Installation Script
# ----------------------------------------------------------------------------
# Format:
# AreaDictionary = {
# "editArea" : {
# "ugcCode": "STZxxx",
# "ugcName": "EditAreaName",
# "ugcCityString": "...CITY1...CITY2",
# "ugcTimeZone": "MST7MDT",
# "fullStateName": "COLORADO",
# "partOfState": "NORTHEAST",
# "stateAbbr": "CO",
# "independentCity": 0,
# "locationName": "GeneralAreaName",
# }
# ...
# }
# ugcTimeZone: This field should be replace with the correct time zone
# for that zone. If it is different from the time zone of
# the local WFO, it's time zone will appear in the header of
# some products in parentheses.
# Using any other strings to define
# the time zone may produce undesirable results.
# The time zone may also be a list of time zones in case
# a forecast zone happens to cover an area that contains
# two time zones.
# e.g. "ugcTimeZone" : ["MST7MDT", "PST8PDT"]
#
# ugcCode: This field contains the ugc coding for this area, such as COZ023
#
# ugcName: This field contains the descriptive name for this area. It
# is used in various products, including Hazard products. This is
# the official county or zone name.
#
# locationName: This field is optional, but provides an alternate name that
# is used in the text of some products to describe the area. The
# FFA product uses this value if available.
#
# ugcCityString: This field contains the list of cities as a string for
# hazard and routine products.
#
# fullStateName: This field is used in hazard products to fully describe
# the state in which this edit area resides.
#
# partOfState: This field describes the location within a state (such as
# NORTHEAST) for this area. It is used in hazard products.
#
# stateAbbr: State Abbreviation for the fullStateName.
#
# independentCity: Set to 0 or 1. Some counties (FIPS coding) are actually
# cities. Setting the flag to 1 will instruct those formatters
# to mention independent cities, rather than include this "county"
# in the county list of the product.
#
AreaDictionary = \
"""
pp = pprint.PrettyPrinter()
s = s + pp.pformat(areadict)
if not os.path.isdir(outputDir):
os.makedirs(outputDir)
outName = os.path.join(outputDir, "AreaDictionary.py")
fh = None
try:
fh, fpath = tempfile.mkstemp(dir=outputDir, suffix=".py")
os.write(fh, s)
os.chmod(fpath, stat.S_IRUSR | stat.S_IWUSR |
stat.S_IRGRP | stat.S_IWGRP |
stat.S_IROTH)
os.close(fh)
fh = None
os.rename(fpath, outName)
except:
LogStream.logProblem("Error writing area dictionary", LogStream.exc())
finally:
if fh is not None:
os.close(fh)
# Utility to create the city location dictionary
def createCityLocation(outputDir, mapDict):
LogStream.logEvent("Generating CityLocation")
citydict = CityLocationDict
if dict != type(mapDict):
import JUtil
mapDict = JUtil.javaObjToPyVal(mapDict)
for mapname in mapDict.keys():
if mapname.find("Cities") == -1:
continue
attList = mapDict[mapname]
for att in attList:
#LogStream.logProblem("att:", att)
ean = att['name']
state = att['st']
county_FIP = att['county_fip']
if len(ean) and len(state) and len(county_FIP):
fip = state + 'C' + county_FIP
if not citydict.has_key(fip):
citydict[fip] = {}
try:
latitude = float(string.strip(att['lat']))
longitude = float(string.strip(att['lon']))
citydict[fip][ean.upper()] = (latitude, longitude)
except:
LogStream.logProblem("Problem creating city location ",
ean, att, LogStream.exc())
s = """
# ----------------------------------------------------------------------------
# This software is in the public domain, furnished "as is", without technical
# support, and with no warranty, express or implied, as to its usefulness for
# any purpose.
#
# CityLocation
# CityLocation file
#
# Author: GFE Installation Script
# ----------------------------------------------------------------------------
# Format:
# CityLocation = {
# "editArea": {"cityName1" : (latitude, longitude),
# "cityName2" : (latitude, longitude),
# ...
# }
# ...
# }
#
# editArea: name of edit area as in AreaDictionary
#
# cityName: name of the city - should be the same as in AreaDictionary.
#
# latitude/longitude: city's lat/lon location.
#
CityLocation = \
"""
pp = pprint.PrettyPrinter()
s = s + pp.pformat(citydict)
if not os.path.isdir(outputDir):
os.makedirs(outputDir)
outName = os.path.join(outputDir, "CityLocation.py")
fh = None
try:
fh, fpath = tempfile.mkstemp(dir=outputDir, suffix=".py")
os.write(fh, s)
os.chmod(fpath, stat.S_IRUSR | stat.S_IWUSR |
stat.S_IRGRP | stat.S_IWGRP |
stat.S_IROTH)
os.close(fh)
fh = None
os.rename(fpath, outName)
except:
LogStream.logProblem("Error writing city location", LogStream.exc())
finally:
if fh is not None:
os.close(fh)