Guest User

Untitled

a guest
Jul 16th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. import re
  2. import string
  3. import sys
  4. import optparse
  5. from django.contrib.gis.gdal import DataSource
  6. from ebpub.metros.models import Metro
  7. from ebpub.streets.models import Block
  8. from ebpub.streets.name_utils import make_pretty_name
  9. from ebpub.utils.text import slugify
  10.  
  11. FIELD_MAP = {
  12. # ESRI # Block
  13. 'LEFT_FROM' : 'left_from_num',
  14. 'LEFT_TO' : 'left_to_num',
  15. 'RIGHT_FROM' : 'right_from_num',
  16. 'RIGHT_TO' : 'right_to_num',
  17. # 'POSTAL_L' : 'left_zip',
  18. # 'POSTAL_R' : 'right_zip',
  19. # 'GEONAME_L' : 'left_city',
  20. # 'GEONAME_R' : 'right_city',
  21. # 'STATE_L' : 'left_state',
  22. # 'STATE_R' : 'right_state',
  23. }
  24.  
  25. NAME_FIELD_MAP = {
  26. 'RD_NAME' : 'street',
  27. 'RD_SUFFIX' : 'suffix',
  28. # 'RD_PREFIX' : 'predir',
  29. 'RD_DIRECTI' : 'postdir',
  30. }
  31.  
  32. # FCC == feature classification code: indicates the type of road
  33. VALID_FCC_PREFIXES = (
  34. 'A1', # primary highway with limited access
  35. 'A2', # primary road without limited access
  36. 'A3', # secondary and connecting road
  37. 'A4' # local, neighborhood, and rural road
  38. )
  39.  
  40. ENCODING = 'cp1252'
  41.  
  42. print >> sys.stderr, 'Starting block importer.'
  43.  
  44. class EsriImporter(object):
  45. def __init__(self, shapefile, city=None, layer_id=0):
  46. print >> sys.stderr, 'Opening %s' % shapefile
  47. ds = DataSource(shapefile)
  48.  
  49. self.layer = ds[layer_id]
  50. self.city = "OTTAWA" #city and city or Metro.objects.get_current().name
  51. self.fcc_pat = re.compile('^(' + '|'.join(VALID_FCC_PREFIXES) + ')\d$')
  52.  
  53. def save(self, verbose=False):
  54. alt_names_suff = (u'',)
  55. num_created = 0
  56. for i, feature in enumerate(self.layer):
  57. #if not self.fcc_pat.search(feature.get('FCC')):
  58. # continue
  59. parent_id = None
  60. fields = {}
  61. for esri_fieldname, block_fieldname in FIELD_MAP.items():
  62. value = feature.get(esri_fieldname)
  63. #print >> sys.stderr, 'Looking at %s' % esri_fieldname
  64.  
  65. if isinstance(value, basestring):
  66. value = value.upper()
  67. elif isinstance(value, int) and value == 0:
  68. value = None
  69. fields[block_fieldname] = value
  70. if not ((fields['left_from_num'] and fields['left_to_num']) or
  71. (fields['right_from_num'] and fields['right_to_num'])):
  72. continue
  73. # Sometimes the "from" number is greater than the "to"
  74. # number in the source data, so we swap them into proper
  75. # ordering
  76. for side in ('left', 'right'):
  77. from_key, to_key = '%s_from_num' % side, '%s_to_num' % side
  78. if fields[from_key] > fields[to_key]:
  79. fields[from_key], fields[to_key] = fields[to_key], fields[from_key]
  80. if feature.geom.geom_name != 'LINESTRING':
  81. continue
  82. for suffix in alt_names_suff:
  83. name_fields = {}
  84. for esri_fieldname, block_fieldname in NAME_FIELD_MAP.items():
  85. key = esri_fieldname + suffix
  86. name_fields[block_fieldname] = feature.get(key).upper()
  87. #if block_fieldname == 'postdir':
  88. #print >> sys.stderr, 'Postdir block %s' % name_fields[block_fieldname]
  89.  
  90.  
  91. if not name_fields['street']:
  92. continue
  93. # Skip blocks with bare number street names and no suffix / type
  94. if not name_fields['suffix'] and re.search('^\d+$', name_fields['street']):
  95. continue
  96. fields.update(name_fields)
  97. for key, val in fields.items():
  98. if isinstance(val, str):
  99. fields[key] = val.decode(ENCODING)
  100.  
  101. fields['street_pretty_name'], fields['pretty_name'] = make_pretty_name(
  102. fields['left_from_num'],
  103. fields['left_to_num'],
  104. fields['right_from_num'],
  105. fields['right_to_num'],
  106. u'',
  107. fields['street'],
  108. fields['suffix'],
  109. fields['postdir'],
  110. )
  111.  
  112. #print >> sys.stderr, 'Looking at block pretty name %s' % fields['street']
  113.  
  114. fields['street_slug'] = slugify(u' '.join((fields['street'], fields['suffix'])))
  115.  
  116. # Watch out for addresses like '247B' which can't be
  117. # saved as an IntegerField.
  118. for addr_key in ('left_from_num', 'left_to_num', 'right_from_num', 'right_to_num'):
  119. fields[addr_key] = fields[addr_key].rstrip(string.letters)
  120. block = Block(**fields)
  121. block.geom = feature.geom.geos
  122. print >> sys.stderr, u'Looking at block %s' % fields['street']
  123.  
  124. block.save()
  125.  
  126. if parent_id is None:
  127. parent_id = block.id
  128. else:
  129. block.parent_id = parent_id
  130. block.save()
  131. num_created += 1
  132. #if verbose:
  133. print >> sys.stderr, 'Created block %s' % block
  134. return num_created
  135.  
  136.  
  137.  
  138. def main(argv=None):
  139. if argv is None:
  140. argv = sys.argv[1:]
  141. parser = optparse.OptionParser(usage='%prog edges.shp')
  142. parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False)
  143. parser.add_option('-c', '--city', dest='city', help='A city name to filter against')
  144. (options, args) = parser.parse_args(argv)
  145. if len(args) != 1:
  146. return parser.error('must provide at least 1 arguments, see usage')
  147. args.append(options.city)
  148. args.append(options.verbose)
  149. esri = EsriImporter(*args)
  150. num_created = esri.save(options.verbose)
  151. #if options.verbose:
  152. # print "Created %d blocks" % num_created
  153.  
  154. if __name__ == '__main__':
  155. sys.exit(main())
Add Comment
Please, Sign In to add comment