us_geo 1.0.3 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +88 -0
- data/MIT_LICENSE.txt +21 -0
- data/README.md +77 -60
- data/UPDATING_TO_VERSION_2.md +172 -0
- data/VERSION +1 -0
- data/db/migrate/20190221054200_create_regions.rb +4 -2
- data/db/migrate/20190221054300_create_divisions.rb +4 -2
- data/db/migrate/20190221054400_create_states.rb +4 -2
- data/db/migrate/20190221054500_create_combined_statistical_areas.rb +4 -2
- data/db/migrate/20190221054600_create_core_based_statistical_areas.rb +4 -2
- data/db/migrate/20190221054650_create_metropolitan_divisions.rb +4 -2
- data/db/migrate/20190221054700_create_counties.rb +4 -3
- data/db/migrate/20190221054800_create_zctas.rb +4 -2
- data/db/migrate/20190221054900_create_zcta_counties.rb +4 -2
- data/db/migrate/20190221055000_create_urban_areas.rb +4 -2
- data/db/migrate/20190221055100_create_urban_area_counties.rb +4 -4
- data/db/migrate/20190221055200_create_zcta_urban_areas.rb +4 -4
- data/db/migrate/20190221060000_create_places.rb +4 -2
- data/db/migrate/20190221061000_create_place_counties.rb +4 -2
- data/db/migrate/20190221062000_create_zcta_places.rb +4 -4
- data/db/migrate/20190221063000_create_county_subdivisions.rb +4 -2
- data/db/migrate/20220722000000_allow_null_zcta_counties_demographics.rb +23 -0
- data/db/migrate/20220722000200_allow_null_zcta_places_demographics.rb +23 -0
- data/db/migrate/20230414000000_add_zcta_primary_place.rb +13 -0
- data/db/migrate/20230414000200_add_demographics_to_regions.rb +28 -0
- data/db/migrate/20230414000300_add_demographics_to_divisions.rb +28 -0
- data/db/migrate/20230414000400_add_demographics_to_states.rb +28 -0
- data/db/migrate/20230414000700_add_short_name_to_core_based_statistical_areas.rb +22 -0
- data/db/migrate/20230414000750_add_short_name_to_combined_statistical_areas.rb +22 -0
- data/db/migrate/20230414000800_create_zcta_mappings.rb +18 -0
- data/db/migrate/20230417000100_create_zcta_county_subdivisions.rb +22 -0
- data/db/migrate/20230417000200_add_unique_name_index_to_county_subdivisions.rb +26 -0
- data/db/migrate/20230417000250_add_zcta_primary_county_subdivision.rb +13 -0
- data/db/migrate/20230417000300_create_urban_area_county_subdivisions.rb +23 -0
- data/db/migrate/20230417000400_allow_null_urban_area_counties_demographics.rb +23 -0
- data/db/migrate/20230417000500_allow_null_zcta_urban_areas_demographics.rb +23 -0
- data/db/migrate/20230417000600_add_additional_time_zone_name_to_counties.rb +13 -0
- data/db/migrate/20230426000100_add_index_on_zctas_geoids.rb +18 -0
- data/db/schema.rb +303 -0
- data/explorer_app/.gitattributes +7 -0
- data/explorer_app/.gitignore +34 -0
- data/explorer_app/Gemfile +38 -0
- data/explorer_app/Rakefile +6 -0
- data/explorer_app/app/assets/images/.keep +0 -0
- data/explorer_app/app/assets/stylesheets/application.css +1 -0
- data/explorer_app/app/controllers/application_controller.rb +64 -0
- data/explorer_app/app/controllers/combined_statistical_areas_controller.rb +12 -0
- data/explorer_app/app/controllers/concerns/.keep +0 -0
- data/explorer_app/app/controllers/core_based_statistical_areas_controller.rb +36 -0
- data/explorer_app/app/controllers/counties_controller.rb +22 -0
- data/explorer_app/app/controllers/county_subdivisions_controller.rb +23 -0
- data/explorer_app/app/controllers/divisions_controller.rb +27 -0
- data/explorer_app/app/controllers/home_controller.rb +6 -0
- data/explorer_app/app/controllers/metropolitan_divisions_controller.rb +27 -0
- data/explorer_app/app/controllers/places_controller.rb +23 -0
- data/explorer_app/app/controllers/regions_controller.rb +13 -0
- data/explorer_app/app/controllers/states_controller.rb +25 -0
- data/explorer_app/app/controllers/urban_areas_controller.rb +24 -0
- data/explorer_app/app/controllers/zctas_controller.rb +23 -0
- data/explorer_app/app/helpers/application_helper.rb +137 -0
- data/explorer_app/app/models/application_record.rb +3 -0
- data/explorer_app/app/models/concerns/.keep +0 -0
- data/explorer_app/app/views/combined_statistical_areas/_table.html.erb +18 -0
- data/explorer_app/app/views/combined_statistical_areas/index.html.erb +7 -0
- data/explorer_app/app/views/combined_statistical_areas/show.html.erb +52 -0
- data/explorer_app/app/views/core_based_statistical_areas/_table.html.erb +32 -0
- data/explorer_app/app/views/core_based_statistical_areas/index.html.erb +19 -0
- data/explorer_app/app/views/core_based_statistical_areas/show.html.erb +60 -0
- data/explorer_app/app/views/counties/_table.html.erb +64 -0
- data/explorer_app/app/views/counties/show.html.erb +96 -0
- data/explorer_app/app/views/county_subdivisions/_table.html.erb +48 -0
- data/explorer_app/app/views/county_subdivisions/show.html.erb +84 -0
- data/explorer_app/app/views/divisions/_table.html.erb +24 -0
- data/explorer_app/app/views/divisions/index.html.erb +3 -0
- data/explorer_app/app/views/divisions/show.html.erb +3 -0
- data/explorer_app/app/views/home/index.html.erb +23 -0
- data/explorer_app/app/views/layouts/application.html.erb +34 -0
- data/explorer_app/app/views/metropolitan_divisions/_table.html.erb +42 -0
- data/explorer_app/app/views/metropolitan_divisions/index.html.erb +8 -0
- data/explorer_app/app/views/metropolitan_divisions/show.html.erb +46 -0
- data/explorer_app/app/views/places/_table.html.erb +47 -0
- data/explorer_app/app/views/places/show.html.erb +92 -0
- data/explorer_app/app/views/regions/_table.html.erb +18 -0
- data/explorer_app/app/views/regions/index.html.erb +7 -0
- data/explorer_app/app/views/regions/show.html.erb +3 -0
- data/explorer_app/app/views/shared/_breadcrumbs.html.erb +13 -0
- data/explorer_app/app/views/shared/_demographics_cells.html.erb +5 -0
- data/explorer_app/app/views/shared/_demographics_headers.html.erb +5 -0
- data/explorer_app/app/views/states/_table.html.erb +31 -0
- data/explorer_app/app/views/states/index.html.erb +7 -0
- data/explorer_app/app/views/states/show.html.erb +54 -0
- data/explorer_app/app/views/urban_areas/_table.html.erb +45 -0
- data/explorer_app/app/views/urban_areas/index.html.erb +19 -0
- data/explorer_app/app/views/urban_areas/show.html.erb +68 -0
- data/explorer_app/app/views/zctas/_table.html.erb +60 -0
- data/explorer_app/app/views/zctas/show.html.erb +104 -0
- data/explorer_app/bin/bundle +109 -0
- data/explorer_app/bin/rails +4 -0
- data/explorer_app/bin/rake +4 -0
- data/explorer_app/bin/setup +33 -0
- data/explorer_app/config/application.rb +37 -0
- data/explorer_app/config/boot.rb +3 -0
- data/explorer_app/config/database.yml +13 -0
- data/explorer_app/config/environment.rb +5 -0
- data/explorer_app/config/environments/development.rb +59 -0
- data/explorer_app/config/initializers/filter_parameter_logging.rb +8 -0
- data/explorer_app/config/locales/en.yml +2 -0
- data/explorer_app/config/puma.rb +43 -0
- data/explorer_app/config/routes.rb +56 -0
- data/explorer_app/config.ru +6 -0
- data/explorer_app/db/seeds.rb +7 -0
- data/explorer_app/lib/assets/.keep +0 -0
- data/explorer_app/lib/tasks/.keep +0 -0
- data/explorer_app/log/.keep +0 -0
- data/explorer_app/public/404.html +67 -0
- data/explorer_app/public/422.html +67 -0
- data/explorer_app/public/500.html +66 -0
- data/explorer_app/public/apple-touch-icon-precomposed.png +0 -0
- data/explorer_app/public/apple-touch-icon.png +0 -0
- data/explorer_app/public/favicon.ico +0 -0
- data/explorer_app/public/robots.txt +1 -0
- data/explorer_app/tmp/.keep +0 -0
- data/explorer_app/tmp/pids/.keep +0 -0
- data/lib/tasks/us_geo/us_geo.rake +44 -3
- data/lib/us_geo/area.rb +44 -0
- data/lib/us_geo/base_record.rb +22 -16
- data/lib/us_geo/combined_statistical_area.rb +18 -8
- data/lib/us_geo/core_based_statistical_area.rb +24 -12
- data/lib/us_geo/county.rb +67 -16
- data/lib/us_geo/county_subdivision.rb +43 -7
- data/lib/us_geo/division.rb +17 -7
- data/lib/us_geo/metropolitan_area.rb +1 -5
- data/lib/us_geo/metropolitan_division.rb +17 -9
- data/lib/us_geo/micropolitan_area.rb +1 -5
- data/lib/us_geo/place.rb +61 -11
- data/lib/us_geo/place_county.rb +1 -4
- data/lib/us_geo/population.rb +26 -0
- data/lib/us_geo/region.rb +18 -8
- data/lib/us_geo/state.rb +32 -11
- data/lib/us_geo/urban_area.rb +46 -16
- data/lib/us_geo/urban_area_county.rb +4 -21
- data/lib/us_geo/urban_area_county_subdivision.rb +51 -0
- data/lib/us_geo/urban_cluster.rb +1 -5
- data/lib/us_geo/urbanized_area.rb +1 -5
- data/lib/us_geo/version.rb +1 -1
- data/lib/us_geo/zcta.rb +90 -13
- data/lib/us_geo/zcta_county.rb +5 -22
- data/lib/us_geo/zcta_county_subdivision.rb +51 -0
- data/lib/us_geo/zcta_mapping.rb +35 -0
- data/lib/us_geo/zcta_place.rb +5 -12
- data/lib/us_geo/zcta_urban_area.rb +3 -20
- data/lib/us_geo.rb +34 -31
- data/us_geo.gemspec +36 -0
- metadata +126 -129
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -75
- data/Rakefile +0 -18
- data/db/migrate/20190221054490_create_designated_market_areas.rb +0 -16
- data/lib/us_geo/demographics.rb +0 -25
- data/lib/us_geo/designated_market_area.rb +0 -30
- data/spec/spec_helper.rb +0 -22
- data/spec/us_geo/base_record_spec.rb +0 -67
- data/spec/us_geo/combined_statistical_area_spec.rb +0 -33
- data/spec/us_geo/core_based_statistical_area_spec.rb +0 -56
- data/spec/us_geo/county_spec.rb +0 -131
- data/spec/us_geo/county_subdivision_spec.rb +0 -37
- data/spec/us_geo/demographics_spec.rb +0 -19
- data/spec/us_geo/designated_market_area_spec.rb +0 -29
- data/spec/us_geo/division_spec.rb +0 -37
- data/spec/us_geo/metropolitan_division_spec.rb +0 -41
- data/spec/us_geo/place_county_spec.rb +0 -39
- data/spec/us_geo/place_spec.rb +0 -71
- data/spec/us_geo/region_spec.rb +0 -36
- data/spec/us_geo/state_spec.rb +0 -70
- data/spec/us_geo/urban_area_county_spec.rb +0 -82
- data/spec/us_geo/urban_area_spec.rb +0 -98
- data/spec/us_geo/zcta_county_spec.rb +0 -82
- data/spec/us_geo/zcta_place_spec.rb +0 -82
- data/spec/us_geo/zcta_spec.rb +0 -99
- data/spec/us_geo/zcta_urban_area_spec.rb +0 -82
data/lib/us_geo/county.rb
CHANGED
@@ -1,45 +1,70 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# County or county equivalent. Counties are composed of zero or more ZCTA's and may
|
6
5
|
# belong to a CBSA. The county's significance withing the CBSA is indicated by the
|
7
6
|
# central flag which indicates if it is a central or outlying county.
|
8
7
|
class County < BaseRecord
|
9
|
-
|
10
|
-
include
|
8
|
+
include Population
|
9
|
+
include Area
|
11
10
|
|
12
11
|
self.primary_key = "geoid"
|
13
12
|
|
14
|
-
belongs_to :designated_market_area, foreign_key: :dma_code, optional: true, inverse_of: :counties
|
15
13
|
belongs_to :core_based_statistical_area, foreign_key: :cbsa_geoid, optional: true, inverse_of: :counties
|
16
14
|
belongs_to :metropolitan_division, foreign_key: :metropolitan_division_geoid, optional: true, inverse_of: :counties
|
17
15
|
belongs_to :state, foreign_key: :state_code, inverse_of: :counties
|
18
16
|
|
19
|
-
has_many :subdivisions, foreign_key: :county_geoid, inverse_of: :county, class_name: "USGeo::CountySubdivision"
|
17
|
+
has_many :subdivisions, -> { not_removed }, foreign_key: :county_geoid, inverse_of: :county, class_name: "USGeo::CountySubdivision"
|
20
18
|
|
21
|
-
has_many :zcta_counties, foreign_key: :county_geoid, inverse_of: :county, dependent: :destroy
|
22
|
-
has_many :zctas, through: :zcta_counties
|
19
|
+
has_many :zcta_counties, -> { not_removed }, foreign_key: :county_geoid, inverse_of: :county, dependent: :destroy
|
20
|
+
has_many :zctas, -> { not_removed }, through: :zcta_counties
|
23
21
|
|
24
22
|
has_many :urban_area_counties, foreign_key: :county_geoid, inverse_of: :county, dependent: :destroy
|
25
23
|
has_many :urban_areas, through: :urban_area_counties
|
26
24
|
|
27
|
-
has_many :place_counties, foreign_key: :county_geoid, inverse_of: :county, dependent: :destroy
|
28
|
-
has_many :places, through: :place_counties
|
25
|
+
has_many :place_counties, -> { not_removed }, foreign_key: :county_geoid, inverse_of: :county, dependent: :destroy
|
26
|
+
has_many :places, -> { not_removed }, through: :place_counties
|
29
27
|
|
30
28
|
validates :geoid, length: {is: 5}
|
31
|
-
validates :name, length: {maximum: 60}
|
32
|
-
validates :short_name, length: {maximum: 30}
|
29
|
+
validates :name, presence: true, length: {maximum: 60}, uniqueness: {scope: :state_code}
|
30
|
+
validates :short_name, presence: true, length: {maximum: 30}, uniqueness: {scope: :state_code}
|
33
31
|
validates :state_code, length: {is: 2}
|
34
32
|
validates :fips_class_code, length: {is: 2}
|
35
33
|
validates :metropolitan_division_geoid, length: {is: 5}, allow_nil: true
|
36
34
|
validates :cbsa_geoid, length: {is: 5}, allow_nil: true
|
37
|
-
validates :dma_code, length: {is: 3}, allow_nil: true
|
38
35
|
validates :land_area, numericality: true, allow_nil: true
|
39
36
|
validates :water_area, numericality: true, allow_nil: true
|
40
37
|
validates :population, numericality: {only_integer: true}, allow_nil: true
|
41
38
|
validates :housing_units, numericality: {only_integer: true}, allow_nil: true
|
42
39
|
|
40
|
+
# @!attribute geoid
|
41
|
+
# @return [String] 5-digit code for the county.
|
42
|
+
|
43
|
+
# @!attribute name
|
44
|
+
# @return [String] Name of the county.
|
45
|
+
|
46
|
+
# @!attribute short_name
|
47
|
+
# @return [String] Short name of the county.
|
48
|
+
|
49
|
+
# @!attribute state_code
|
50
|
+
# @return [String] 2-letter code for the state.
|
51
|
+
|
52
|
+
# @!attribute fips_class_code
|
53
|
+
# @return [String] 2-character FIPS class code.
|
54
|
+
|
55
|
+
# @!attribute time_zone_name
|
56
|
+
# @return [String] Time zone name.
|
57
|
+
|
58
|
+
# @!attribute time_zone_2_name
|
59
|
+
# @return [String] Time zone name.
|
60
|
+
|
61
|
+
# @!method central?
|
62
|
+
# @return [Boolean] True if the county is a central county in the CBSA.
|
63
|
+
|
64
|
+
# @!method combined_statistical_area
|
65
|
+
# @return [USGeo::CombinedStatisticalArea] Combined statistical area that the county belongs to.
|
66
|
+
delegate :combined_statistical_area, to: :core_based_statistical_area, allow_nil: true
|
67
|
+
|
43
68
|
class << self
|
44
69
|
def load!(uri = nil)
|
45
70
|
location = data_uri(uri || "counties.csv")
|
@@ -53,14 +78,14 @@ module USGeo
|
|
53
78
|
record.state_code = row["State"]
|
54
79
|
record.cbsa_geoid = row["CBSA"]
|
55
80
|
record.metropolitan_division_geoid = row["Metropolitan Division"]
|
56
|
-
record.dma_code = row["DMA"]
|
57
81
|
record.time_zone_name = row["Time Zone"]
|
82
|
+
record.time_zone_2_name = row["Time Zone 2"]
|
58
83
|
record.fips_class_code = row["FIPS Class"]
|
59
84
|
record.central = (row["Central"] == "T")
|
60
85
|
record.population = row["Population"]
|
61
86
|
record.housing_units = row["Housing Units"]
|
62
|
-
record.land_area =
|
63
|
-
record.water_area =
|
87
|
+
record.land_area = row["Land Area"]
|
88
|
+
record.water_area = row["Water Area"]
|
64
89
|
record.lat = row["Latitude"]
|
65
90
|
record.lng = row["Longitude"]
|
66
91
|
end
|
@@ -69,6 +94,13 @@ module USGeo
|
|
69
94
|
end
|
70
95
|
end
|
71
96
|
|
97
|
+
# Full name of the county with the state.
|
98
|
+
#
|
99
|
+
# @return [String]
|
100
|
+
def full_name
|
101
|
+
"#{name}, #{state_code}"
|
102
|
+
end
|
103
|
+
|
72
104
|
def state_fips
|
73
105
|
geoid[0, 2]
|
74
106
|
end
|
@@ -79,12 +111,31 @@ module USGeo
|
|
79
111
|
|
80
112
|
# Return the CBSA only if it is a metropolitan area.
|
81
113
|
def metropolitan_area
|
82
|
-
core_based_statistical_area if core_based_statistical_area
|
114
|
+
core_based_statistical_area if core_based_statistical_area&.metropolitan?
|
83
115
|
end
|
84
116
|
|
117
|
+
# Return a single time zone for the county. If the county has two time zones,
|
118
|
+
# only one is returned.
|
119
|
+
#
|
120
|
+
# @return [ActiveSupport::TimeZone, nil]
|
85
121
|
def time_zone
|
86
122
|
ActiveSupport::TimeZone[time_zone_name] if time_zone_name
|
87
123
|
end
|
88
124
|
|
125
|
+
# Get all time zones for the county.
|
126
|
+
#
|
127
|
+
# @return [Array<ActiveSupport::TimeZone>]
|
128
|
+
def time_zones
|
129
|
+
[time_zone_name, time_zone_2_name].compact.collect do |tz_name|
|
130
|
+
ActiveSupport::TimeZone[tz_name]
|
131
|
+
end.compact
|
132
|
+
end
|
133
|
+
|
134
|
+
# True if the county is an outlying county in the CBSA.
|
135
|
+
#
|
136
|
+
# @return [Boolean]
|
137
|
+
def outlying?
|
138
|
+
!central?
|
139
|
+
end
|
89
140
|
end
|
90
141
|
end
|
@@ -1,24 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# County subdivision.
|
6
5
|
class CountySubdivision < BaseRecord
|
7
|
-
|
8
|
-
include
|
6
|
+
include Population
|
7
|
+
include Area
|
9
8
|
|
10
9
|
self.primary_key = "geoid"
|
11
10
|
|
12
11
|
belongs_to :county, foreign_key: :county_geoid, inverse_of: :subdivisions
|
13
12
|
|
13
|
+
has_many :zcta_county_subdivisions, -> { not_removed }, foreign_key: :county_subdivision_geoid, inverse_of: :county_subdivision, dependent: :destroy
|
14
|
+
has_many :zctas, -> { not_removed }, through: :zcta_county_subdivisions
|
15
|
+
|
16
|
+
has_many :urban_area_county_subdivisions, foreign_key: :county_subdivision_geoid, inverse_of: :county_subdivision, dependent: :destroy
|
17
|
+
has_many :urban_areas, through: :urban_area_county_subdivisions
|
18
|
+
|
14
19
|
validates :geoid, length: {is: 10}
|
15
|
-
validates :name, length: {maximum: 60}
|
20
|
+
validates :name, presence: true, length: {maximum: 60}, uniqueness: {scope: :county_geoid}
|
16
21
|
validates :fips_class_code, length: {is: 2}
|
17
22
|
validates :land_area, numericality: true, allow_nil: true
|
18
23
|
validates :water_area, numericality: true, allow_nil: true
|
19
24
|
validates :population, numericality: {only_integer: true}, allow_nil: true
|
20
25
|
validates :housing_units, numericality: {only_integer: true}, allow_nil: true
|
21
26
|
|
27
|
+
# @!attribute geoid
|
28
|
+
# @return [String] 10-digit code for the subdivision.
|
29
|
+
|
30
|
+
# @!attribute name
|
31
|
+
# @return [String] Name of the subdivision.
|
32
|
+
|
33
|
+
# @!attribute fips_class_code
|
34
|
+
# @return [String] 2-character FIPS class code.
|
35
|
+
|
36
|
+
# @!method :core_based_statistical_area
|
37
|
+
# @return [CoreBasedStatisticalArea] Core-based statistical area the subdivision is in.
|
38
|
+
delegate :core_based_statistical_area, to: :county
|
39
|
+
|
40
|
+
# @!method :combined_statistical_area
|
41
|
+
# @return [CombinedStatisticalArea] Combined statistical area the subdivision is in.
|
42
|
+
delegate :combined_statistical_area, to: :county
|
43
|
+
|
44
|
+
# @!method :metropolitan_division
|
45
|
+
# @return [MetropolitanDivision] Metropolitan division the subdivision is in.
|
46
|
+
delegate :metropolitan_division, to: :county
|
47
|
+
|
48
|
+
# @!method :state
|
49
|
+
# @return [State] State the subdivision is in.
|
50
|
+
delegate :state, to: :county
|
51
|
+
|
52
|
+
# @!method :state_code
|
53
|
+
# @return [String] 2-character state code.
|
54
|
+
delegate :state_code, to: :county
|
55
|
+
|
22
56
|
class << self
|
23
57
|
def load!(uri = nil)
|
24
58
|
location = data_uri(uri || "county_subdivisions.csv")
|
@@ -32,15 +66,17 @@ module USGeo
|
|
32
66
|
record.fips_class_code = row["FIPS Class"]
|
33
67
|
record.population = row["Population"]
|
34
68
|
record.housing_units = row["Housing Units"]
|
35
|
-
record.land_area =
|
36
|
-
record.water_area =
|
69
|
+
record.land_area = row["Land Area"]
|
70
|
+
record.water_area = row["Water Area"]
|
37
71
|
record.lat = row["Latitude"]
|
38
72
|
record.lng = row["Longitude"]
|
73
|
+
|
74
|
+
duplicate = where.not(geoid: record.geoid).find_by(name: record.name, county_geoid: record.county_geoid)
|
75
|
+
duplicate&.update!(name: "#{record.name} (deleted)", status: BaseRecord::STATUS_REMOVED)
|
39
76
|
end
|
40
77
|
end
|
41
78
|
end
|
42
79
|
end
|
43
80
|
end
|
44
|
-
|
45
81
|
end
|
46
82
|
end
|
data/lib/us_geo/division.rb
CHANGED
@@ -1,29 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# U.S. regional division composed of states.
|
6
5
|
class Division < BaseRecord
|
6
|
+
include Population
|
7
|
+
include Area
|
7
8
|
|
8
9
|
belongs_to :region, inverse_of: :divisions
|
9
|
-
has_many :states, inverse_of: :division
|
10
|
+
has_many :states, -> { not_removed }, inverse_of: :division
|
11
|
+
|
12
|
+
validates :name, presence: true, length: {maximum: 30}, uniqueness: true
|
13
|
+
|
14
|
+
# @!attribute id
|
15
|
+
# @return [Integer] ID of the division.
|
10
16
|
|
11
|
-
|
17
|
+
# @!attribute name
|
18
|
+
# @return [String] Name of the division.
|
12
19
|
|
13
20
|
class << self
|
14
21
|
def load!(uri = nil)
|
15
22
|
location = data_uri(uri || "divisions.csv")
|
16
|
-
|
23
|
+
|
17
24
|
import! do
|
18
25
|
load_data_file(location) do |row|
|
19
|
-
load_record!(id: row["
|
20
|
-
record.name = row["
|
26
|
+
load_record!(id: row["ID"]) do |record|
|
27
|
+
record.name = row["Name"]
|
21
28
|
record.region_id = row["Region ID"]
|
29
|
+
record.population = row["Population"]
|
30
|
+
record.housing_units = row["Housing Units"]
|
31
|
+
record.land_area = row["Land Area"]
|
32
|
+
record.water_area = row["Water Area"]
|
22
33
|
end
|
23
34
|
end
|
24
35
|
end
|
25
36
|
end
|
26
37
|
end
|
27
|
-
|
28
38
|
end
|
29
39
|
end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# Core based statistical area with a population greater then 50,000.
|
6
5
|
class MetropolitanArea < CoreBasedStatisticalArea
|
7
|
-
|
8
6
|
def metropolitan?
|
9
7
|
true
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
def micropolitan?
|
13
11
|
false
|
14
12
|
end
|
15
|
-
|
16
13
|
end
|
17
|
-
|
18
14
|
end
|
@@ -1,23 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# Division of very large metropolitian areas into groups of approximately 2.5 million people.
|
6
5
|
class MetropolitanDivision < BaseRecord
|
7
|
-
|
8
|
-
include
|
6
|
+
include Population
|
7
|
+
include Area
|
9
8
|
|
10
9
|
self.primary_key = "geoid"
|
11
10
|
|
12
|
-
has_many :counties, foreign_key: :metropolitan_division_geoid, inverse_of: :metropolitan_division
|
11
|
+
has_many :counties, -> { not_removed }, foreign_key: :metropolitan_division_geoid, inverse_of: :metropolitan_division
|
13
12
|
belongs_to :core_based_statistical_area, foreign_key: :cbsa_geoid, optional: true, inverse_of: :metropolitan_divisions
|
14
13
|
|
15
14
|
validates :geoid, length: {is: 5}
|
16
|
-
validates :name, length: {maximum: 60}
|
15
|
+
validates :name, presence: true, length: {maximum: 60}, uniqueness: true
|
17
16
|
validates :land_area, numericality: true, presence: true
|
18
17
|
validates :water_area, numericality: true, presence: true
|
19
18
|
validates :population, numericality: {only_integer: true}, presence: true
|
20
|
-
validates :housing_units, numericality: {only_integer: true},
|
19
|
+
validates :housing_units, numericality: {only_integer: true}, presence: true
|
20
|
+
|
21
|
+
# @!attribute geoid
|
22
|
+
# @return [String] 5-digit code for the metropolitan division.
|
23
|
+
|
24
|
+
# @!attribute name
|
25
|
+
# @return [String] Name of the metropolitan division.
|
26
|
+
|
27
|
+
# @!method combined_statistical_area
|
28
|
+
# @return [CombinedStatisticalArea, nil] Combined statistical area that the metropolitan division is a part of.
|
29
|
+
delegate :combined_statistical_area, to: :core_based_statistical_area, allow_nil: true
|
21
30
|
|
22
31
|
class << self
|
23
32
|
def load!(uri = nil)
|
@@ -30,13 +39,12 @@ module USGeo
|
|
30
39
|
record.cbsa_geoid = row["CBSA"]
|
31
40
|
record.population = row["Population"]
|
32
41
|
record.housing_units = row["Housing Units"]
|
33
|
-
record.land_area =
|
34
|
-
record.water_area =
|
42
|
+
record.land_area = row["Land Area"]
|
43
|
+
record.water_area = row["Water Area"]
|
35
44
|
end
|
36
45
|
end
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
40
|
-
|
41
49
|
end
|
42
50
|
end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# Core based statistical area with a population greater then 10,000 but less than 50,000.
|
6
5
|
class MicropolitanArea < CoreBasedStatisticalArea
|
7
|
-
|
8
6
|
def metropolitan?
|
9
7
|
false
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
def micropolitan?
|
13
11
|
true
|
14
12
|
end
|
15
|
-
|
16
13
|
end
|
17
|
-
|
18
14
|
end
|
data/lib/us_geo/place.rb
CHANGED
@@ -1,29 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# Division of very large metropolitian areas into groups of approximately 2.5 million people.
|
6
5
|
class Place < BaseRecord
|
7
|
-
|
8
|
-
include
|
6
|
+
include Population
|
7
|
+
include Area
|
9
8
|
|
10
9
|
self.primary_key = "geoid"
|
11
10
|
|
12
|
-
|
13
|
-
|
11
|
+
# !@method zcta_places
|
12
|
+
# @return [ActiveRecord::Relation<ZctaPlace>] ZCTA to place mapping.
|
13
|
+
has_many :zcta_places, -> { not_removed }, foreign_key: :place_geoid, inverse_of: :place, dependent: :destroy
|
14
|
+
|
15
|
+
# !@method zctas
|
16
|
+
# @return [ActiveRecord::Relation<Zcta>] ZCTA's that overlap with this place.
|
17
|
+
has_many :zctas, -> { not_removed }, through: :zcta_places
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
# !@method place_counties
|
20
|
+
# @return [ActiveRecord::Relation<PlaceCounty>] Place to county mapping.
|
21
|
+
has_many :place_counties, -> { not_removed }, foreign_key: :place_geoid, inverse_of: :place, dependent: :destroy
|
17
22
|
|
23
|
+
# !@method counties
|
24
|
+
# @return [ActiveRecord::Relation<County>] Counties that this place is a part of.
|
25
|
+
has_many :counties, -> { not_removed }, through: :place_counties
|
26
|
+
|
27
|
+
# !@method primary_county
|
28
|
+
# @return [County] County that contains most of the place.
|
18
29
|
belongs_to :primary_county, foreign_key: :primary_county_geoid, class_name: "USGeo::County"
|
30
|
+
|
31
|
+
# !@method urban_area
|
32
|
+
# @return [UrbanArea] Urban area that the place is a part of.
|
19
33
|
belongs_to :urban_area, foreign_key: :urban_area_geoid, optional: true, class_name: "USGeo::UrbanArea"
|
34
|
+
|
35
|
+
# !@method state
|
36
|
+
# @return [State] State that the place is in.
|
20
37
|
belongs_to :state, foreign_key: :state_code, inverse_of: :places
|
21
38
|
|
22
39
|
validates :geoid, length: {is: 7}
|
23
40
|
validates :state_code, length: {is: 2}
|
24
41
|
validates :primary_county_geoid, length: {is: 5}
|
25
42
|
validates :urban_area_geoid, length: {is: 5}, allow_nil: true
|
26
|
-
validates :name, length: {maximum: 60}
|
43
|
+
validates :name, presence: true, length: {maximum: 60}
|
27
44
|
validates :short_name, length: {maximum: 30}
|
28
45
|
validates :fips_class_code, length: {is: 2}
|
29
46
|
validates :land_area, numericality: true, allow_nil: true
|
@@ -31,6 +48,40 @@ module USGeo
|
|
31
48
|
validates :population, numericality: {only_integer: true}, allow_nil: true
|
32
49
|
validates :housing_units, numericality: {only_integer: true}, allow_nil: true
|
33
50
|
|
51
|
+
# @!attribute geoid
|
52
|
+
# @return [String] 7-digit code for the place.
|
53
|
+
|
54
|
+
# @!attribute name
|
55
|
+
# @return [String] Name of the place.
|
56
|
+
|
57
|
+
# @!attribute short_name
|
58
|
+
# @return [String] Short name of the place.
|
59
|
+
|
60
|
+
# @!attribute state_code
|
61
|
+
# @return [String] 2-letter code for the state.
|
62
|
+
|
63
|
+
# @!attribute fips_class_code
|
64
|
+
# @return [String] 2-character FIPS class code.
|
65
|
+
|
66
|
+
# @!method combined_statistical_area
|
67
|
+
# @return [CombinedStatisticalArea, nil] Combined statistical area that the place is a part of.
|
68
|
+
delegate :combined_statistical_area, to: :primary_county, allow_nil: true
|
69
|
+
|
70
|
+
# @!method core_based_statistical_area
|
71
|
+
# @return [CoreBasedStatisticalArea, nil] Core-based statistical area that the place is a part of.
|
72
|
+
delegate :core_based_statistical_area, to: :primary_county, allow_nil: true
|
73
|
+
|
74
|
+
# @!method metropolitan_division
|
75
|
+
# @return [MetropolitanDivision, nil] Metropolitan division that the place is a part of.
|
76
|
+
delegate :metropolitan_division, to: :primary_county, allow_nil: true
|
77
|
+
|
78
|
+
# Full name of the place as short name plus the state.
|
79
|
+
#
|
80
|
+
# @return [String]
|
81
|
+
def full_name
|
82
|
+
"#{short_name}, #{state_code}"
|
83
|
+
end
|
84
|
+
|
34
85
|
class << self
|
35
86
|
def load!(uri = nil)
|
36
87
|
location = data_uri(uri || "places.csv")
|
@@ -47,8 +98,8 @@ module USGeo
|
|
47
98
|
record.fips_class_code = row["FIPS Class"]
|
48
99
|
record.population = row["Population"]
|
49
100
|
record.housing_units = row["Housing Units"]
|
50
|
-
record.land_area =
|
51
|
-
record.water_area =
|
101
|
+
record.land_area = row["Land Area"]
|
102
|
+
record.water_area = row["Water Area"]
|
52
103
|
record.lat = row["Latitude"]
|
53
104
|
record.lng = row["Longitude"]
|
54
105
|
end
|
@@ -56,6 +107,5 @@ module USGeo
|
|
56
107
|
end
|
57
108
|
end
|
58
109
|
end
|
59
|
-
|
60
110
|
end
|
61
111
|
end
|
data/lib/us_geo/place_county.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
|
-
# Mapping of urban areas to counties they overlap with.
|
4
|
+
# Mapping of places to counties they overlap with.
|
6
5
|
class PlaceCounty < BaseRecord
|
7
|
-
|
8
6
|
belongs_to :county, foreign_key: :county_geoid, inverse_of: :place_counties
|
9
7
|
belongs_to :place, foreign_key: :place_geoid, inverse_of: :place_counties
|
10
8
|
|
@@ -23,6 +21,5 @@ module USGeo
|
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
28
25
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module USGeo
|
4
|
+
# This module is mixed into all models with a population and land area.
|
5
|
+
module Population
|
6
|
+
# @!attribute population
|
7
|
+
# @return [Integer, nil] Total population of the area.
|
8
|
+
|
9
|
+
# @!attribute housing_units
|
10
|
+
# @return [Integer, nil] Total housing units in the area.
|
11
|
+
|
12
|
+
# Population per square mile.
|
13
|
+
#
|
14
|
+
# @return [Float, nil]
|
15
|
+
def population_density
|
16
|
+
population.to_f / land_area if population && land_area.to_f > 0
|
17
|
+
end
|
18
|
+
|
19
|
+
# Population per square kilometer.
|
20
|
+
#
|
21
|
+
# @return [Float, nil]
|
22
|
+
def population_density_km
|
23
|
+
population.to_f / land_area_km if population && land_area.to_f > 0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/us_geo/region.rb
CHANGED
@@ -1,28 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# U.S. region.
|
6
5
|
class Region < BaseRecord
|
6
|
+
include Population
|
7
|
+
include Area
|
8
|
+
|
9
|
+
has_many :divisions, -> { not_removed }, inverse_of: :region
|
10
|
+
has_many :states, -> { not_removed }, inverse_of: :region
|
7
11
|
|
8
|
-
|
9
|
-
has_many :states, inverse_of: :region
|
12
|
+
validates :name, presence: true, length: {maximum: 30}, uniqueness: true
|
10
13
|
|
11
|
-
|
14
|
+
# @!attribute id
|
15
|
+
# @return [Integer] ID of the region.
|
16
|
+
|
17
|
+
# @!attribute name
|
18
|
+
# @return [String] Name of the region.
|
12
19
|
|
13
20
|
class << self
|
14
21
|
def load!(uri = nil)
|
15
|
-
location = data_uri(uri || "
|
22
|
+
location = data_uri(uri || "regions.csv")
|
16
23
|
|
17
24
|
import! do
|
18
25
|
load_data_file(location) do |row|
|
19
|
-
load_record!(id: row["
|
20
|
-
record.name = row["
|
26
|
+
load_record!(id: row["ID"]) do |record|
|
27
|
+
record.name = row["Name"]
|
28
|
+
record.population = row["Population"]
|
29
|
+
record.housing_units = row["Housing Units"]
|
30
|
+
record.land_area = row["Land Area"]
|
31
|
+
record.water_area = row["Water Area"]
|
21
32
|
end
|
22
33
|
end
|
23
34
|
end
|
24
35
|
end
|
25
36
|
end
|
26
|
-
|
27
37
|
end
|
28
38
|
end
|
data/lib/us_geo/state.rb
CHANGED
@@ -1,31 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module USGeo
|
4
|
-
|
5
4
|
# U.S. state or territory.
|
6
5
|
class State < BaseRecord
|
6
|
+
include Population
|
7
|
+
include Area
|
7
8
|
|
8
9
|
STATE_TYPE = "state"
|
9
10
|
DISTRICT_TYPE = "district"
|
10
11
|
TERRITORY_TYPE = "territory"
|
11
|
-
|
12
|
+
|
12
13
|
self.primary_key = "code"
|
13
14
|
self.inheritance_column = :_type_disabled
|
14
15
|
|
15
16
|
belongs_to :region, optional: -> { territory? }, inverse_of: :states
|
16
17
|
belongs_to :division, optional: -> { territory? }, inverse_of: :states
|
17
|
-
has_many :counties, foreign_key: :state_code, inverse_of: :state
|
18
|
-
has_many :places, foreign_key: :state_code, inverse_of: :state
|
19
18
|
|
20
|
-
|
19
|
+
has_many :counties, -> { not_removed }, foreign_key: :state_code, inverse_of: :state
|
20
|
+
has_many :places, -> { not_removed }, foreign_key: :state_code, inverse_of: :state
|
21
|
+
|
22
|
+
validates :code, length: {is: 2}, uniqueness: true
|
21
23
|
validates :fips, length: {is: 2}
|
22
|
-
validates :name, length: {maximum: 30}
|
24
|
+
validates :name, presence: true, length: {maximum: 30}, uniqueness: true
|
23
25
|
validates :type, inclusion: [STATE_TYPE, DISTRICT_TYPE, TERRITORY_TYPE]
|
24
26
|
|
27
|
+
# @!attribute code
|
28
|
+
# @return [String] 2-letter postal code of the state.
|
29
|
+
|
30
|
+
# @!attribute name
|
31
|
+
# @return [String] Name of the state.
|
32
|
+
|
33
|
+
# @!attribute fips
|
34
|
+
# @return [String] 2-digit FIPS code of the state.
|
35
|
+
|
36
|
+
# @!attribute type
|
37
|
+
# @return [String] Type of the state or territory.
|
38
|
+
|
39
|
+
# @!method :region
|
40
|
+
# @return [Region] Region the state is in.
|
41
|
+
delegate :region, to: :division, allow_nil: true
|
42
|
+
|
25
43
|
class << self
|
26
44
|
def load!(uri = nil)
|
27
45
|
location = data_uri(uri || "states.csv")
|
28
|
-
|
46
|
+
|
29
47
|
import! do
|
30
48
|
load_data_file(location) do |row|
|
31
49
|
load_record!(code: row["Code"]) do |record|
|
@@ -34,23 +52,26 @@ module USGeo
|
|
34
52
|
record.fips = row["FIPS"]
|
35
53
|
record.region_id = row["Region ID"]
|
36
54
|
record.division_id = row["Division ID"]
|
55
|
+
record.population = row["Population"]
|
56
|
+
record.housing_units = row["Housing Units"]
|
57
|
+
record.land_area = row["Land Area"]
|
58
|
+
record.water_area = row["Water Area"]
|
37
59
|
end
|
38
60
|
end
|
39
61
|
end
|
40
62
|
end
|
41
63
|
end
|
42
|
-
|
64
|
+
|
43
65
|
def state?
|
44
66
|
type == STATE_TYPE
|
45
67
|
end
|
46
|
-
|
68
|
+
|
47
69
|
def territory?
|
48
70
|
type == TERRITORY_TYPE
|
49
71
|
end
|
50
|
-
|
72
|
+
|
51
73
|
def district?
|
52
74
|
type == DISTRICT_TYPE
|
53
75
|
end
|
54
|
-
|
55
76
|
end
|
56
77
|
end
|