us_geo 1.0.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -0
  3. data/MIT_LICENSE.txt +21 -0
  4. data/README.md +77 -60
  5. data/UPDATING_TO_VERSION_2.md +172 -0
  6. data/VERSION +1 -0
  7. data/db/migrate/20190221054200_create_regions.rb +4 -2
  8. data/db/migrate/20190221054300_create_divisions.rb +4 -2
  9. data/db/migrate/20190221054400_create_states.rb +4 -2
  10. data/db/migrate/20190221054500_create_combined_statistical_areas.rb +4 -2
  11. data/db/migrate/20190221054600_create_core_based_statistical_areas.rb +4 -2
  12. data/db/migrate/20190221054650_create_metropolitan_divisions.rb +4 -2
  13. data/db/migrate/20190221054700_create_counties.rb +4 -3
  14. data/db/migrate/20190221054800_create_zctas.rb +4 -2
  15. data/db/migrate/20190221054900_create_zcta_counties.rb +4 -2
  16. data/db/migrate/20190221055000_create_urban_areas.rb +4 -2
  17. data/db/migrate/20190221055100_create_urban_area_counties.rb +4 -4
  18. data/db/migrate/20190221055200_create_zcta_urban_areas.rb +4 -4
  19. data/db/migrate/20190221060000_create_places.rb +4 -2
  20. data/db/migrate/20190221061000_create_place_counties.rb +4 -2
  21. data/db/migrate/20190221062000_create_zcta_places.rb +4 -4
  22. data/db/migrate/20190221063000_create_county_subdivisions.rb +4 -2
  23. data/db/migrate/20220722000000_allow_null_zcta_counties_demographics.rb +23 -0
  24. data/db/migrate/20220722000200_allow_null_zcta_places_demographics.rb +23 -0
  25. data/db/migrate/20230414000000_add_zcta_primary_place.rb +13 -0
  26. data/db/migrate/20230414000200_add_demographics_to_regions.rb +28 -0
  27. data/db/migrate/20230414000300_add_demographics_to_divisions.rb +28 -0
  28. data/db/migrate/20230414000400_add_demographics_to_states.rb +28 -0
  29. data/db/migrate/20230414000700_add_short_name_to_core_based_statistical_areas.rb +22 -0
  30. data/db/migrate/20230414000750_add_short_name_to_combined_statistical_areas.rb +22 -0
  31. data/db/migrate/20230414000800_create_zcta_mappings.rb +18 -0
  32. data/db/migrate/20230417000100_create_zcta_county_subdivisions.rb +22 -0
  33. data/db/migrate/20230417000200_add_unique_name_index_to_county_subdivisions.rb +26 -0
  34. data/db/migrate/20230417000250_add_zcta_primary_county_subdivision.rb +13 -0
  35. data/db/migrate/20230417000300_create_urban_area_county_subdivisions.rb +23 -0
  36. data/db/migrate/20230417000400_allow_null_urban_area_counties_demographics.rb +23 -0
  37. data/db/migrate/20230417000500_allow_null_zcta_urban_areas_demographics.rb +23 -0
  38. data/db/migrate/20230417000600_add_additional_time_zone_name_to_counties.rb +13 -0
  39. data/db/schema.rb +303 -0
  40. data/explorer_app/.gitattributes +7 -0
  41. data/explorer_app/.gitignore +34 -0
  42. data/explorer_app/Gemfile +38 -0
  43. data/explorer_app/Rakefile +6 -0
  44. data/explorer_app/app/assets/images/.keep +0 -0
  45. data/explorer_app/app/assets/stylesheets/application.css +1 -0
  46. data/explorer_app/app/controllers/application_controller.rb +64 -0
  47. data/explorer_app/app/controllers/combined_statistical_areas_controller.rb +12 -0
  48. data/explorer_app/app/controllers/concerns/.keep +0 -0
  49. data/explorer_app/app/controllers/core_based_statistical_areas_controller.rb +36 -0
  50. data/explorer_app/app/controllers/counties_controller.rb +22 -0
  51. data/explorer_app/app/controllers/county_subdivisions_controller.rb +23 -0
  52. data/explorer_app/app/controllers/divisions_controller.rb +27 -0
  53. data/explorer_app/app/controllers/home_controller.rb +6 -0
  54. data/explorer_app/app/controllers/metropolitan_divisions_controller.rb +27 -0
  55. data/explorer_app/app/controllers/places_controller.rb +23 -0
  56. data/explorer_app/app/controllers/regions_controller.rb +13 -0
  57. data/explorer_app/app/controllers/states_controller.rb +25 -0
  58. data/explorer_app/app/controllers/urban_areas_controller.rb +24 -0
  59. data/explorer_app/app/controllers/zctas_controller.rb +23 -0
  60. data/explorer_app/app/helpers/application_helper.rb +137 -0
  61. data/explorer_app/app/models/application_record.rb +3 -0
  62. data/explorer_app/app/models/concerns/.keep +0 -0
  63. data/explorer_app/app/views/combined_statistical_areas/_table.html.erb +18 -0
  64. data/explorer_app/app/views/combined_statistical_areas/index.html.erb +7 -0
  65. data/explorer_app/app/views/combined_statistical_areas/show.html.erb +52 -0
  66. data/explorer_app/app/views/core_based_statistical_areas/_table.html.erb +32 -0
  67. data/explorer_app/app/views/core_based_statistical_areas/index.html.erb +19 -0
  68. data/explorer_app/app/views/core_based_statistical_areas/show.html.erb +60 -0
  69. data/explorer_app/app/views/counties/_table.html.erb +64 -0
  70. data/explorer_app/app/views/counties/show.html.erb +96 -0
  71. data/explorer_app/app/views/county_subdivisions/_table.html.erb +48 -0
  72. data/explorer_app/app/views/county_subdivisions/show.html.erb +84 -0
  73. data/explorer_app/app/views/divisions/_table.html.erb +24 -0
  74. data/explorer_app/app/views/divisions/index.html.erb +3 -0
  75. data/explorer_app/app/views/divisions/show.html.erb +3 -0
  76. data/explorer_app/app/views/home/index.html.erb +23 -0
  77. data/explorer_app/app/views/layouts/application.html.erb +34 -0
  78. data/explorer_app/app/views/metropolitan_divisions/_table.html.erb +42 -0
  79. data/explorer_app/app/views/metropolitan_divisions/index.html.erb +8 -0
  80. data/explorer_app/app/views/metropolitan_divisions/show.html.erb +46 -0
  81. data/explorer_app/app/views/places/_table.html.erb +47 -0
  82. data/explorer_app/app/views/places/show.html.erb +92 -0
  83. data/explorer_app/app/views/regions/_table.html.erb +18 -0
  84. data/explorer_app/app/views/regions/index.html.erb +7 -0
  85. data/explorer_app/app/views/regions/show.html.erb +3 -0
  86. data/explorer_app/app/views/shared/_breadcrumbs.html.erb +13 -0
  87. data/explorer_app/app/views/shared/_demographics_cells.html.erb +5 -0
  88. data/explorer_app/app/views/shared/_demographics_headers.html.erb +5 -0
  89. data/explorer_app/app/views/states/_table.html.erb +31 -0
  90. data/explorer_app/app/views/states/index.html.erb +7 -0
  91. data/explorer_app/app/views/states/show.html.erb +54 -0
  92. data/explorer_app/app/views/urban_areas/_table.html.erb +45 -0
  93. data/explorer_app/app/views/urban_areas/index.html.erb +19 -0
  94. data/explorer_app/app/views/urban_areas/show.html.erb +68 -0
  95. data/explorer_app/app/views/zctas/_table.html.erb +60 -0
  96. data/explorer_app/app/views/zctas/show.html.erb +104 -0
  97. data/explorer_app/bin/bundle +109 -0
  98. data/explorer_app/bin/rails +4 -0
  99. data/explorer_app/bin/rake +4 -0
  100. data/explorer_app/bin/setup +33 -0
  101. data/explorer_app/config/application.rb +37 -0
  102. data/explorer_app/config/boot.rb +3 -0
  103. data/explorer_app/config/database.yml +13 -0
  104. data/explorer_app/config/environment.rb +5 -0
  105. data/explorer_app/config/environments/development.rb +59 -0
  106. data/explorer_app/config/initializers/filter_parameter_logging.rb +8 -0
  107. data/explorer_app/config/locales/en.yml +2 -0
  108. data/explorer_app/config/puma.rb +43 -0
  109. data/explorer_app/config/routes.rb +56 -0
  110. data/explorer_app/config.ru +6 -0
  111. data/explorer_app/db/seeds.rb +7 -0
  112. data/explorer_app/lib/assets/.keep +0 -0
  113. data/explorer_app/lib/tasks/.keep +0 -0
  114. data/explorer_app/log/.keep +0 -0
  115. data/explorer_app/public/404.html +67 -0
  116. data/explorer_app/public/422.html +67 -0
  117. data/explorer_app/public/500.html +66 -0
  118. data/explorer_app/public/apple-touch-icon-precomposed.png +0 -0
  119. data/explorer_app/public/apple-touch-icon.png +0 -0
  120. data/explorer_app/public/favicon.ico +0 -0
  121. data/explorer_app/public/robots.txt +1 -0
  122. data/explorer_app/tmp/.keep +0 -0
  123. data/explorer_app/tmp/pids/.keep +0 -0
  124. data/lib/tasks/us_geo/us_geo.rake +44 -3
  125. data/lib/us_geo/area.rb +44 -0
  126. data/lib/us_geo/base_record.rb +22 -16
  127. data/lib/us_geo/combined_statistical_area.rb +18 -8
  128. data/lib/us_geo/core_based_statistical_area.rb +24 -12
  129. data/lib/us_geo/county.rb +67 -16
  130. data/lib/us_geo/county_subdivision.rb +43 -7
  131. data/lib/us_geo/division.rb +17 -7
  132. data/lib/us_geo/metropolitan_area.rb +1 -5
  133. data/lib/us_geo/metropolitan_division.rb +17 -9
  134. data/lib/us_geo/micropolitan_area.rb +1 -5
  135. data/lib/us_geo/place.rb +61 -11
  136. data/lib/us_geo/place_county.rb +1 -4
  137. data/lib/us_geo/population.rb +26 -0
  138. data/lib/us_geo/region.rb +18 -8
  139. data/lib/us_geo/state.rb +32 -11
  140. data/lib/us_geo/urban_area.rb +46 -16
  141. data/lib/us_geo/urban_area_county.rb +4 -21
  142. data/lib/us_geo/urban_area_county_subdivision.rb +51 -0
  143. data/lib/us_geo/urban_cluster.rb +1 -5
  144. data/lib/us_geo/urbanized_area.rb +1 -5
  145. data/lib/us_geo/version.rb +1 -1
  146. data/lib/us_geo/zcta.rb +90 -13
  147. data/lib/us_geo/zcta_county.rb +5 -22
  148. data/lib/us_geo/zcta_county_subdivision.rb +51 -0
  149. data/lib/us_geo/zcta_mapping.rb +35 -0
  150. data/lib/us_geo/zcta_place.rb +5 -12
  151. data/lib/us_geo/zcta_urban_area.rb +3 -20
  152. data/lib/us_geo.rb +34 -31
  153. data/us_geo.gemspec +36 -0
  154. metadata +125 -129
  155. data/Gemfile +0 -5
  156. data/Gemfile.lock +0 -75
  157. data/Rakefile +0 -18
  158. data/db/migrate/20190221054490_create_designated_market_areas.rb +0 -16
  159. data/lib/us_geo/demographics.rb +0 -25
  160. data/lib/us_geo/designated_market_area.rb +0 -30
  161. data/spec/spec_helper.rb +0 -22
  162. data/spec/us_geo/base_record_spec.rb +0 -67
  163. data/spec/us_geo/combined_statistical_area_spec.rb +0 -33
  164. data/spec/us_geo/core_based_statistical_area_spec.rb +0 -56
  165. data/spec/us_geo/county_spec.rb +0 -131
  166. data/spec/us_geo/county_subdivision_spec.rb +0 -37
  167. data/spec/us_geo/demographics_spec.rb +0 -19
  168. data/spec/us_geo/designated_market_area_spec.rb +0 -29
  169. data/spec/us_geo/division_spec.rb +0 -37
  170. data/spec/us_geo/metropolitan_division_spec.rb +0 -41
  171. data/spec/us_geo/place_county_spec.rb +0 -39
  172. data/spec/us_geo/place_spec.rb +0 -71
  173. data/spec/us_geo/region_spec.rb +0 -36
  174. data/spec/us_geo/state_spec.rb +0 -70
  175. data/spec/us_geo/urban_area_county_spec.rb +0 -82
  176. data/spec/us_geo/urban_area_spec.rb +0 -98
  177. data/spec/us_geo/zcta_county_spec.rb +0 -82
  178. data/spec/us_geo/zcta_place_spec.rb +0 -82
  179. data/spec/us_geo/zcta_spec.rb +0 -99
  180. data/spec/us_geo/zcta_urban_area_spec.rb +0 -82
@@ -1,22 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
4
  # Urban areas are split into either urbanized areas (population > 50,000) or urban cluster (population < 50,000).
6
5
  class UrbanArea < BaseRecord
7
-
8
- include Demographics
6
+ include Area
7
+ include Population
9
8
 
10
9
  self.primary_key = "geoid"
11
10
  self.store_full_sti_class = false
12
11
 
12
+ # !@method urban_area_counties
13
+ # @return [ActiveRecord::Relation<USGeo::UrbanAreaCounty>] County to urban area mapping.
13
14
  has_many :urban_area_counties, foreign_key: :urban_area_geoid, inverse_of: :urban_area, dependent: :destroy
15
+
16
+ # !@method counties
17
+ # @return [ActiveRecord::Relation<USGeo::County>] Counties that overlap with the urban area.
14
18
  has_many :counties, through: :urban_area_counties
19
+
20
+ # !@method primary_county
21
+ # @return [USGeo::County] Primary county that contains most of the urban area.
15
22
  belongs_to :primary_county, foreign_key: :primary_county_geoid, class_name: "USGeo::County"
16
-
23
+
24
+ # !@method urban_area_county_subdivisions
25
+ # @return [ActiveRecord::Relation<USGeo::UrbanAreaCountySubdivision>] County subdivision to urban area mapping.
26
+ has_many :urban_area_county_subdivisions, foreign_key: :urban_area_geoid, inverse_of: :urban_area, dependent: :destroy
27
+
28
+ # !@method county_subdivisions
29
+ # @return [ActiveRecord::Relation<USGeo::CountySubdivision>] County subdivisions that overlap with the urban area.
30
+ has_many :county_subdivisions, through: :urban_area_county_subdivisions
31
+
32
+ # !@method zcta_urban_areas
33
+ # @return [ActiveRecord::Relation<USGeo::ZctaUrbanArea>] Zip code to urban area mapping.
17
34
  has_many :zcta_urban_areas, foreign_key: :urban_area_geoid, inverse_of: :urban_area, dependent: :destroy
35
+
36
+ # !@method zctas
37
+ # @return [ActiveRecord::Relation<USGeo::Zcta>] Zip codes that overlap with the urban area.
18
38
  has_many :zctas, through: :zcta_urban_areas
19
39
 
40
+ # !@method places
41
+ # @return [ActiveRecord::Relation<USGeo::Place>] Places that overlap with the urban area.
42
+ has_many :places, foreign_key: :urban_area_geoid, inverse_of: :urban_area
43
+
20
44
  validates :geoid, length: {is: 5}
21
45
  validates :primary_county_geoid, length: {is: 5}
22
46
  validates :name, length: {maximum: 90}
@@ -26,26 +50,33 @@ module USGeo
26
50
  validates :population, numericality: {only_integer: true}, presence: true
27
51
  validates :housing_units, numericality: {only_integer: true}, presence: true
28
52
 
29
- delegate :core_based_statistical_area, :designated_market_area, :state, :state_code, :time_zone, to: :primary_county, allow_nil: true
53
+ # !@method combined_statistical_area
54
+ # @return [USGeo::CombinedStatisticalArea, nil] Combined statistical area that the urban area is a part of.
55
+ delegate :combined_statistical_area, to: :primary_county, allow_nil: true
56
+
57
+ # !@method core_based_statistical_area
58
+ # @return [USGeo::CoreBasedStatisticalArea, nil] Core-based statistical area that the urban area is a part of.
59
+ delegate :core_based_statistical_area, to: :primary_county, allow_nil: true
60
+
61
+ # !@method metropolitan_division
62
+ # @return [USGeo::MetropolitanDivision, nil] Metropolitan division that the urban area is a part of.
63
+ delegate :metropolitan_division, to: :primary_county, allow_nil: true
30
64
 
31
- before_save do
32
- self.short_name = name.sub(" Urbanized Area", "").sub(" Urban Cluster", "") if name
33
- end
34
-
35
65
  class << self
36
66
  def load!(uri = nil)
37
67
  location = data_uri(uri || "urban_areas.csv")
38
-
68
+
39
69
  import! do
40
70
  load_data_file(location) do |row|
41
71
  load_record!(geoid: row["GEOID"]) do |record|
42
- record.type = (row["Population"].to_i >= 50_000 ? "UrbanizedArea" : "UrbanCluster")
72
+ record.type = ((row["Population"].to_i >= 50_000) ? "UrbanizedArea" : "UrbanCluster")
43
73
  record.name = row["Name"]
44
- record.primary_county_geoid = row["Primary County"]
74
+ record.short_name = row["Short Name"]
75
+ record.primary_county_geoid = row["Primary County GEOID"]
45
76
  record.population = row["Population"]
46
77
  record.housing_units = row["Housing Units"]
47
- record.land_area = area_meters_to_miles(row["Land Area"])
48
- record.water_area = area_meters_to_miles(row["Water Area"])
78
+ record.land_area = row["Land Area"]
79
+ record.water_area = row["Water Area"]
49
80
  record.lat = row["Latitude"]
50
81
  record.lng = row["Longitude"]
51
82
  end
@@ -57,10 +88,9 @@ module USGeo
57
88
  def urbanized?
58
89
  raise NotImplementedError
59
90
  end
60
-
91
+
61
92
  def cluster?
62
93
  raise NotImplementedError
63
94
  end
64
-
65
95
  end
66
96
  end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
4
  # Mapping of urban areas to counties they overlap with.
6
5
  class UrbanAreaCounty < BaseRecord
7
-
8
- include Demographics
6
+ include Area
9
7
 
10
8
  belongs_to :county, foreign_key: :county_geoid, inverse_of: :urban_area_counties
11
9
  belongs_to :urban_area, foreign_key: :urban_area_geoid, inverse_of: :urban_area_counties
@@ -14,31 +12,22 @@ module USGeo
14
12
  validates :urban_area_geoid, length: {is: 5}
15
13
  validates :land_area, numericality: true, presence: true
16
14
  validates :water_area, numericality: true, presence: true
17
- validates :population, numericality: {only_integer: true}, presence: true
18
- validates :housing_units, numericality: {only_integer: true}, presence: true
19
15
 
20
16
  class << self
21
17
  def load!(uri = nil)
22
18
  location = data_uri(uri || "urban_area_counties.csv")
23
-
19
+
24
20
  import! do
25
21
  load_data_file(location) do |row|
26
22
  load_record!(urban_area_geoid: row["Urban Area GEOID"], county_geoid: row["County GEOID"]) do |record|
27
- record.population = row["Population"]
28
- record.housing_units = row["Housing Units"]
29
- record.land_area = area_meters_to_miles(row["Land Area"])
30
- record.water_area = area_meters_to_miles(row["Water Area"])
23
+ record.land_area = row["Land Area"]
24
+ record.water_area = row["Water Area"]
31
25
  end
32
26
  end
33
27
  end
34
28
  end
35
29
  end
36
30
 
37
- # Percentage of the urban area population.
38
- def percent_urban_area_population
39
- population.to_f / urban_area.population.to_f
40
- end
41
-
42
31
  # Percentage of the urban area land area.
43
32
  def percent_urban_area_land_area
44
33
  land_area / urban_area.land_area
@@ -49,11 +38,6 @@ module USGeo
49
38
  total_area / urban_area.total_area
50
39
  end
51
40
 
52
- # Percentage of the county population.
53
- def percent_county_population
54
- population.to_f / county.population.to_f
55
- end
56
-
57
41
  # Percentage of the county land area.
58
42
  def percent_county_land_area
59
43
  land_area / county.land_area
@@ -63,6 +47,5 @@ module USGeo
63
47
  def percent_county_total_area
64
48
  total_area / county.total_area
65
49
  end
66
-
67
50
  end
68
51
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module USGeo
4
+ # Mapping of urban areas to counties they overlap with.
5
+ class UrbanAreaCountySubdivision < BaseRecord
6
+ include Area
7
+
8
+ belongs_to :county_subdivision, foreign_key: :county_subdivision_geoid, inverse_of: :urban_area_county_subdivisions
9
+ belongs_to :urban_area, foreign_key: :urban_area_geoid, inverse_of: :urban_area_county_subdivisions
10
+
11
+ validates :county_subdivision_geoid, length: {is: 10}
12
+ validates :urban_area_geoid, length: {is: 5}
13
+ validates :land_area, numericality: true, presence: true
14
+ validates :water_area, numericality: true, presence: true
15
+
16
+ class << self
17
+ def load!(uri = nil)
18
+ location = data_uri(uri || "urban_area_county_subdivisions.csv")
19
+
20
+ import! do
21
+ load_data_file(location) do |row|
22
+ load_record!(urban_area_geoid: row["Urban Area GEOID"], county_subdivision_geoid: row["County Subdivision GEOID"]) do |record|
23
+ record.land_area = row["Land Area"]
24
+ record.water_area = row["Water Area"]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ # Percentage of the urban area land area.
32
+ def percent_urban_area_land_area
33
+ land_area / urban_area.land_area
34
+ end
35
+
36
+ # Percentage of the urban area total area.
37
+ def percent_urban_area_total_area
38
+ total_area / urban_area.total_area
39
+ end
40
+
41
+ # Percentage of the county land area.
42
+ def percent_county_subdivision_land_area
43
+ land_area / county_subdivision.land_area
44
+ end
45
+
46
+ # Percentage of the county total area.
47
+ def percent_county_subdivision_total_area
48
+ total_area / county_subdivision.total_area
49
+ end
50
+ end
51
+ end
@@ -1,18 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
4
  # Urban area with population < 50,000.
6
5
  class UrbanCluster < UrbanArea
7
-
8
6
  def urbanized?
9
7
  false
10
8
  end
11
-
9
+
12
10
  def cluster?
13
11
  true
14
12
  end
15
-
16
13
  end
17
-
18
14
  end
@@ -1,18 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
4
  # Urban area with population >= 50,000.
6
5
  class UrbanizedArea < UrbanArea
7
-
8
6
  def urbanized?
9
7
  true
10
8
  end
11
-
9
+
12
10
  def cluster?
13
11
  false
14
12
  end
15
-
16
13
  end
17
-
18
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
- VERSION = "1.0.3"
4
+ VERSION = File.read(File.expand_path("../../VERSION", __dir__)).chomp.freeze
5
5
  end
data/lib/us_geo/zcta.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
4
  # ZIP code tabulation area. These roughly map to U.S. Postal service ZIP codes, but
6
5
  # are designed for geographic and demographic purposes instead of mail routing. In particular
7
6
  # certain optimizations that the Postal Service makes to optimize mail routing are
@@ -10,25 +9,74 @@ module USGeo
10
9
  # ZCTA's can span counties, but the one with the majority of the residents is identified
11
10
  # as the primary county for when a single county is required.
12
11
  #
13
- # ZCTA's can span urbanized area, but the one with the majority of the residents is identified
14
- # as the primary urbanized area for when a single area is required.
12
+ # ZCTA's can span places, but the one with the majority of the residents is identified
13
+ # as the primary place for when a single area is required.
15
14
  class Zcta < BaseRecord
16
-
17
- include Demographics
15
+ include Population
16
+ include Area
18
17
 
19
18
  self.table_name = "us_geo_zctas"
20
19
  self.primary_key = "zipcode"
21
20
 
22
- has_many :zcta_counties, foreign_key: :zipcode, inverse_of: :zcta, dependent: :destroy
23
- has_many :counties, through: :zcta_counties
21
+ # @!method self.for_zipcode
22
+ # This scope will search for ZCTA's via the ZCTAMappings table. This is useful
23
+ # when you have a retired ZIP code and want to find the current ZCTA for that ZIP code.
24
+ #
25
+ # @param zipcode [String] ZIP code to search for.
26
+ # @return [ActiveRecord::Relation] ZCTA's matching the given ZIP code.
27
+ scope :for_zipcode, ->(zipcode) { left_outer_joins(:zcta_mappings).where(ZctaMapping.table_name => {zipcode: zipcode}).or(left_outer_joins(:zcta_mappings).where(zipcode: zipcode)).distinct }
28
+
29
+ # @!method zcta_counties
30
+ # @return [ActiveRecord::Relation] ZCTA to county mappings.
31
+ has_many :zcta_counties, -> { not_removed }, foreign_key: :zipcode, inverse_of: :zcta, dependent: :destroy
32
+
33
+ # @!method counties
34
+ # @return [ActiveRecord::Relation] Counties that this ZCTA is a part of.
35
+ has_many :counties, -> { not_removed }, through: :zcta_counties
36
+
37
+ # @!method primary_county
38
+ # @return [USGeo::County] County that contains most of the ZCTA's land area.
24
39
  belongs_to :primary_county, foreign_key: :primary_county_geoid, class_name: "USGeo::County"
25
40
 
41
+ # @!method zcta_urban_areas
42
+ # @return [ActiveRecord::Relation] ZCTA to urban area mappings.
26
43
  has_many :zcta_urban_areas, foreign_key: :zipcode, inverse_of: :zcta, dependent: :destroy
44
+
45
+ # @!method urban_areas
46
+ # @return [ActiveRecord::Relation] Urban areas that this ZCTA is a part of.
27
47
  has_many :urban_areas, through: :zcta_urban_areas
48
+
49
+ # @!method primary_urban_area
50
+ # @return [USGeo::UrbanArea] Urban area that contains most of the ZCTA's land area.
28
51
  belongs_to :primary_urban_area, foreign_key: :primary_urban_area_geoid, class_name: "USGeo::UrbanArea"
29
52
 
30
- has_many :zcta_places, foreign_key: :zipcode, inverse_of: :zcta, dependent: :destroy
31
- has_many :places, through: :zcta_places
53
+ # @!method zcta_county_subdivisions
54
+ # @return [ActiveRecord::Relation] ZCTA to county subdivision mappings.
55
+ has_many :zcta_county_subdivisions, -> { not_removed }, foreign_key: :zipcode, inverse_of: :zcta, dependent: :destroy
56
+
57
+ # @!method county_subdivisions
58
+ # @return [ActiveRecord::Relation] County subdivisions that this ZCTA is a part of.
59
+ has_many :county_subdivisions, -> { not_removed }, through: :zcta_county_subdivisions
60
+
61
+ # @!method primary_county_subdivision
62
+ # @return [USGeo::CountySubdivision] County subdivision that contains most of the ZCTA's land area.
63
+ belongs_to :primary_county_subdivision, foreign_key: :primary_county_subdivision_geoid, class_name: "USGeo::CountySubdivision"
64
+
65
+ # @!method zcta_places
66
+ # @return [ActiveRecord::Relation] ZCTA to place mappings.
67
+ has_many :zcta_places, -> { not_removed }, foreign_key: :zipcode, inverse_of: :zcta, dependent: :destroy
68
+
69
+ # @!method places
70
+ # @return [ActiveRecord::Relation] Places that this ZCTA is a part of.
71
+ has_many :places, -> { not_removed }, through: :zcta_places
72
+
73
+ # @!method primary_place
74
+ # @return [USGeo::Place] Place that contains most of the ZCTA's land area.
75
+ belongs_to :primary_place, foreign_key: :primary_place_geoid, class_name: "USGeo::Place"
76
+
77
+ # @!method zcta_mappings
78
+ # @return [ActiveRecord::Relation] 2010 ZCTA to current ZCTA mappings.
79
+ has_many :zcta_mappings, -> { not_removed }, foreign_key: :zcta_zipcode, inverse_of: :zcta, dependent: :destroy
32
80
 
33
81
  validates :zipcode, length: {is: 5}
34
82
  validates :land_area, numericality: true, presence: true
@@ -36,7 +84,35 @@ module USGeo
36
84
  validates :population, numericality: {only_integer: true}, presence: true
37
85
  validates :housing_units, numericality: {only_integer: true}, presence: true
38
86
 
39
- delegate :core_based_statistical_area, :designated_market_area, :state, :state_code, :time_zone, to: :primary_county, allow_nil: true
87
+ # @!attribute zipcode
88
+ # @return [String] 5-digit ZIP code.
89
+
90
+ # @!method combined_statistical_area
91
+ # @return [USGeo::CombinedStatisticalArea, nil] Combined statistical area that contains the ZCTA.
92
+ delegate :combined_statistical_area, to: :primary_county, allow_nil: true
93
+
94
+ # @!method core_based_statistical_area
95
+ # @return [USGeo::CoreBasedStatisticalArea, nil] Core-based statistical area that contains the ZCTA.
96
+ delegate :core_based_statistical_area, to: :primary_county, allow_nil: true
97
+
98
+ # @!method metropolitan_division
99
+ # @return [USGeo::MetropolitanDivision, nil] Metropolitan division that contains the ZCTA.
100
+ delegate :metropolitan_division, to: :primary_county, allow_nil: true
101
+
102
+ # @!method state
103
+ # @return [USGeo::State] State that contains the ZCTA.
104
+ delegate :state, to: :primary_county, allow_nil: true
105
+
106
+ # @!method state_code
107
+ # @return [String] State code that contains the ZCTA.
108
+ delegate :state_code, to: :primary_county, allow_nil: true
109
+
110
+ # @!method time_zone
111
+ # Get the time zone for the primary county containing the ZCTA. Note that this is not
112
+ # necessarily the time zone for the ZCTA itself since a handful of counties span multiple
113
+ # time zones.
114
+ # @return [ActiveSupport::TimeZone, nil] Time zone for the ZCTA.
115
+ delegate :time_zone, to: :primary_county, allow_nil: true
40
116
 
41
117
  class << self
42
118
  def load!(uri = nil)
@@ -47,10 +123,12 @@ module USGeo
47
123
  load_record!(zipcode: row["ZCTA5"]) do |record|
48
124
  record.primary_county_geoid = row["Primary County"]
49
125
  record.primary_urban_area_geoid = row["Primary Urban Area"]
126
+ record.primary_county_subdivision_geoid = row["Primary County Subdivision"]
127
+ record.primary_place_geoid = row["Primary Place"]
50
128
  record.population = row["Population"]
51
129
  record.housing_units = row["Housing Units"]
52
- record.land_area = area_meters_to_miles(row["Land Area"])
53
- record.water_area = area_meters_to_miles(row["Water Area"])
130
+ record.land_area = row["Land Area"]
131
+ record.water_area = row["Water Area"]
54
132
  record.lat = row["Latitude"]
55
133
  record.lng = row["Longitude"]
56
134
  end
@@ -58,6 +136,5 @@ module USGeo
58
136
  end
59
137
  end
60
138
  end
61
-
62
139
  end
63
140
  end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
4
  # Mapping of ZCTA's to counties they overlap with.
6
5
  class ZctaCounty < BaseRecord
7
-
8
- include Demographics
6
+ include Area
9
7
 
10
8
  belongs_to :zcta, foreign_key: :zipcode, inverse_of: :zcta_counties
11
9
  belongs_to :county, foreign_key: :county_geoid, inverse_of: :zcta_counties
@@ -14,31 +12,22 @@ module USGeo
14
12
  validates :county_geoid, length: {is: 5}
15
13
  validates :land_area, numericality: true, presence: true
16
14
  validates :water_area, numericality: true, presence: true
17
- validates :population, numericality: {only_integer: true}, presence: true
18
- validates :housing_units, numericality: {only_integer: true}, presence: true
19
15
 
20
16
  class << self
21
17
  def load!(uri = nil)
22
18
  location = data_uri(uri || "zcta_counties.csv")
23
-
19
+
24
20
  import! do
25
21
  load_data_file(location) do |row|
26
- load_record!(zipcode: row["ZCTA5"], county_geoid: row["GEOID"]) do |record|
27
- record.population = row["Population"]
28
- record.housing_units = row["Housing Units"]
29
- record.land_area = area_meters_to_miles(row["Land Area"])
30
- record.water_area = area_meters_to_miles(row["Water Area"])
22
+ load_record!(zipcode: row["ZCTA5"], county_geoid: row["County GEOID"]) do |record|
23
+ record.land_area = row["Land Area"]
24
+ record.water_area = row["Water Area"]
31
25
  end
32
26
  end
33
27
  end
34
28
  end
35
29
  end
36
30
 
37
- # Percentage of the ZCTA population.
38
- def percent_zcta_population
39
- population.to_f / zcta.population.to_f
40
- end
41
-
42
31
  # Percentage of the ZCTA land area.
43
32
  def percent_zcta_land_area
44
33
  land_area / zcta.land_area
@@ -49,11 +38,6 @@ module USGeo
49
38
  total_area / zcta.total_area
50
39
  end
51
40
 
52
- # Percentage of the county population.
53
- def percent_county_population
54
- population.to_f / county.population.to_f
55
- end
56
-
57
41
  # Percentage of the county land area.
58
42
  def percent_county_land_area
59
43
  land_area / county.land_area
@@ -63,6 +47,5 @@ module USGeo
63
47
  def percent_county_total_area
64
48
  total_area / county.total_area
65
49
  end
66
-
67
50
  end
68
51
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module USGeo
4
+ # Mapping of ZCTA's to counties they overlap with.
5
+ class ZctaCountySubdivision < BaseRecord
6
+ include Area
7
+
8
+ belongs_to :zcta, foreign_key: :zipcode, inverse_of: :zcta_county_subdivisions
9
+ belongs_to :county_subdivision, foreign_key: :county_subdivision_geoid, inverse_of: :zcta_county_subdivisions
10
+
11
+ validates :zipcode, length: {is: 5}
12
+ validates :county_subdivision_geoid, length: {is: 10}
13
+ validates :land_area, numericality: true, presence: true
14
+ validates :water_area, numericality: true, presence: true
15
+
16
+ class << self
17
+ def load!(uri = nil)
18
+ location = data_uri(uri || "zcta_county_subdivisions.csv")
19
+
20
+ import! do
21
+ load_data_file(location) do |row|
22
+ load_record!(zipcode: row["ZCTA5"], county_subdivision_geoid: row["County Subdivision GEOID"]) do |record|
23
+ record.land_area = row["Land Area"]
24
+ record.water_area = row["Water Area"]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ # Percentage of the ZCTA land area.
32
+ def percent_zcta_land_area
33
+ land_area / zcta.land_area
34
+ end
35
+
36
+ # Percentage of the ZCTA total area.
37
+ def percent_zcta_total_area
38
+ total_area / zcta.total_area
39
+ end
40
+
41
+ # Percentage of the county subdivision land area.
42
+ def percent_county_subdivision_land_area
43
+ land_area / county_subdivision.land_area
44
+ end
45
+
46
+ # Percentage of the county subdivision total area.
47
+ def percent_county_subdivision_total_area
48
+ total_area / county_subdivision.total_area
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module USGeo
4
+ # Mapping of ZIP codes to currently active ZCTA's. The U.S. Postal Service
5
+ # maintains the list of active ZIP codes which can change as population moves
6
+ # around. New ZIP codes are created when a new area is developed and old ZIP
7
+ # are retired when an area is losing population. The Census Bureau updates
8
+ # the list of ZCTA's every 10 years.
9
+ #
10
+ # This mapping table allows looking up the current ZCTA for a ZIP code even
11
+ # if that ZIP code was retired and is no longer in the ZCTA table.
12
+ class ZctaMapping < BaseRecord
13
+ self.table_name = "us_geo_zcta_mappings"
14
+ self.primary_key = "zipcode"
15
+
16
+ belongs_to :zcta, foreign_key: :zcta_zipcode, inverse_of: :zcta_mappings
17
+
18
+ validates :zipcode, length: {is: 5}
19
+ validates :zcta_zipcode, length: {is: 5}
20
+
21
+ class << self
22
+ def load!(uri = nil)
23
+ location = data_uri(uri || "zcta_mappings.csv")
24
+
25
+ import! do
26
+ load_data_file(location) do |row|
27
+ load_record!(zipcode: row["ZIP Code"]) do |record|
28
+ record.zcta_zipcode = row["Active ZCTA5"]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USGeo
4
-
5
- # Mapping of ZCTA's to urban areas they overlap with.
4
+ # Mapping of ZCTA's to places they overlap with.
6
5
  class ZctaPlace < BaseRecord
7
-
8
- include Demographics
6
+ include Area
9
7
 
10
8
  belongs_to :zcta, foreign_key: :zipcode, inverse_of: :zcta_places
11
9
  belongs_to :place, foreign_key: :place_geoid, inverse_of: :zcta_places
@@ -14,20 +12,16 @@ module USGeo
14
12
  validates :place_geoid, length: {is: 7}
15
13
  validates :land_area, numericality: true, presence: true
16
14
  validates :water_area, numericality: true, presence: true
17
- validates :population, numericality: {only_integer: true}, presence: true
18
- validates :housing_units, numericality: {only_integer: true}, presence: true
19
15
 
20
16
  class << self
21
17
  def load!(uri = nil)
22
18
  location = data_uri(uri || "zcta_places.csv")
23
-
19
+
24
20
  import! do
25
21
  load_data_file(location) do |row|
26
22
  load_record!(zipcode: row["ZCTA5"], place_geoid: row["Place GEOID"]) do |record|
27
- record.population = row["Population"]
28
- record.housing_units = row["Housing Units"]
29
- record.land_area = area_meters_to_miles(row["Land Area"])
30
- record.water_area = area_meters_to_miles(row["Water Area"])
23
+ record.land_area = row["Land Area"]
24
+ record.water_area = row["Water Area"]
31
25
  end
32
26
  end
33
27
  end
@@ -63,6 +57,5 @@ module USGeo
63
57
  def percent_place_total_area
64
58
  total_area / place.total_area
65
59
  end
66
-
67
60
  end
68
61
  end