us_geo 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -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/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 +125 -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
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<style>
|
|
7
|
+
.rails-default-error-page {
|
|
8
|
+
background-color: #EFEFEF;
|
|
9
|
+
color: #2E2F30;
|
|
10
|
+
text-align: center;
|
|
11
|
+
font-family: arial, sans-serif;
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.rails-default-error-page div.dialog {
|
|
16
|
+
width: 95%;
|
|
17
|
+
max-width: 33em;
|
|
18
|
+
margin: 4em auto 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.rails-default-error-page div.dialog > div {
|
|
22
|
+
border: 1px solid #CCC;
|
|
23
|
+
border-right-color: #999;
|
|
24
|
+
border-left-color: #999;
|
|
25
|
+
border-bottom-color: #BBB;
|
|
26
|
+
border-top: #B00100 solid 4px;
|
|
27
|
+
border-top-left-radius: 9px;
|
|
28
|
+
border-top-right-radius: 9px;
|
|
29
|
+
background-color: white;
|
|
30
|
+
padding: 7px 12% 0;
|
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.rails-default-error-page h1 {
|
|
35
|
+
font-size: 100%;
|
|
36
|
+
color: #730E15;
|
|
37
|
+
line-height: 1.5em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rails-default-error-page div.dialog > p {
|
|
41
|
+
margin: 0 0 1em;
|
|
42
|
+
padding: 1em;
|
|
43
|
+
background-color: #F7F7F7;
|
|
44
|
+
border: 1px solid #CCC;
|
|
45
|
+
border-right-color: #999;
|
|
46
|
+
border-left-color: #999;
|
|
47
|
+
border-bottom-color: #999;
|
|
48
|
+
border-bottom-left-radius: 4px;
|
|
49
|
+
border-bottom-right-radius: 4px;
|
|
50
|
+
border-top-color: #DADADA;
|
|
51
|
+
color: #666;
|
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
55
|
+
</head>
|
|
56
|
+
|
|
57
|
+
<body class="rails-default-error-page">
|
|
58
|
+
<!-- This file lives in public/404.html -->
|
|
59
|
+
<div class="dialog">
|
|
60
|
+
<div>
|
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
63
|
+
</div>
|
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
65
|
+
</div>
|
|
66
|
+
</body>
|
|
67
|
+
</html>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<style>
|
|
7
|
+
.rails-default-error-page {
|
|
8
|
+
background-color: #EFEFEF;
|
|
9
|
+
color: #2E2F30;
|
|
10
|
+
text-align: center;
|
|
11
|
+
font-family: arial, sans-serif;
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.rails-default-error-page div.dialog {
|
|
16
|
+
width: 95%;
|
|
17
|
+
max-width: 33em;
|
|
18
|
+
margin: 4em auto 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.rails-default-error-page div.dialog > div {
|
|
22
|
+
border: 1px solid #CCC;
|
|
23
|
+
border-right-color: #999;
|
|
24
|
+
border-left-color: #999;
|
|
25
|
+
border-bottom-color: #BBB;
|
|
26
|
+
border-top: #B00100 solid 4px;
|
|
27
|
+
border-top-left-radius: 9px;
|
|
28
|
+
border-top-right-radius: 9px;
|
|
29
|
+
background-color: white;
|
|
30
|
+
padding: 7px 12% 0;
|
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.rails-default-error-page h1 {
|
|
35
|
+
font-size: 100%;
|
|
36
|
+
color: #730E15;
|
|
37
|
+
line-height: 1.5em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rails-default-error-page div.dialog > p {
|
|
41
|
+
margin: 0 0 1em;
|
|
42
|
+
padding: 1em;
|
|
43
|
+
background-color: #F7F7F7;
|
|
44
|
+
border: 1px solid #CCC;
|
|
45
|
+
border-right-color: #999;
|
|
46
|
+
border-left-color: #999;
|
|
47
|
+
border-bottom-color: #999;
|
|
48
|
+
border-bottom-left-radius: 4px;
|
|
49
|
+
border-bottom-right-radius: 4px;
|
|
50
|
+
border-top-color: #DADADA;
|
|
51
|
+
color: #666;
|
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
55
|
+
</head>
|
|
56
|
+
|
|
57
|
+
<body class="rails-default-error-page">
|
|
58
|
+
<!-- This file lives in public/422.html -->
|
|
59
|
+
<div class="dialog">
|
|
60
|
+
<div>
|
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
63
|
+
</div>
|
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
65
|
+
</div>
|
|
66
|
+
</body>
|
|
67
|
+
</html>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<style>
|
|
7
|
+
.rails-default-error-page {
|
|
8
|
+
background-color: #EFEFEF;
|
|
9
|
+
color: #2E2F30;
|
|
10
|
+
text-align: center;
|
|
11
|
+
font-family: arial, sans-serif;
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.rails-default-error-page div.dialog {
|
|
16
|
+
width: 95%;
|
|
17
|
+
max-width: 33em;
|
|
18
|
+
margin: 4em auto 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.rails-default-error-page div.dialog > div {
|
|
22
|
+
border: 1px solid #CCC;
|
|
23
|
+
border-right-color: #999;
|
|
24
|
+
border-left-color: #999;
|
|
25
|
+
border-bottom-color: #BBB;
|
|
26
|
+
border-top: #B00100 solid 4px;
|
|
27
|
+
border-top-left-radius: 9px;
|
|
28
|
+
border-top-right-radius: 9px;
|
|
29
|
+
background-color: white;
|
|
30
|
+
padding: 7px 12% 0;
|
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.rails-default-error-page h1 {
|
|
35
|
+
font-size: 100%;
|
|
36
|
+
color: #730E15;
|
|
37
|
+
line-height: 1.5em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rails-default-error-page div.dialog > p {
|
|
41
|
+
margin: 0 0 1em;
|
|
42
|
+
padding: 1em;
|
|
43
|
+
background-color: #F7F7F7;
|
|
44
|
+
border: 1px solid #CCC;
|
|
45
|
+
border-right-color: #999;
|
|
46
|
+
border-left-color: #999;
|
|
47
|
+
border-bottom-color: #999;
|
|
48
|
+
border-bottom-left-radius: 4px;
|
|
49
|
+
border-bottom-right-radius: 4px;
|
|
50
|
+
border-top-color: #DADADA;
|
|
51
|
+
color: #666;
|
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
55
|
+
</head>
|
|
56
|
+
|
|
57
|
+
<body class="rails-default-error-page">
|
|
58
|
+
<!-- This file lives in public/500.html -->
|
|
59
|
+
<div class="dialog">
|
|
60
|
+
<div>
|
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
62
|
+
</div>
|
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
64
|
+
</div>
|
|
65
|
+
</body>
|
|
66
|
+
</html>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
|
|
File without changes
|
|
File without changes
|
|
@@ -6,7 +6,6 @@ namespace :us_geo do
|
|
|
6
6
|
regions: USGeo::Region,
|
|
7
7
|
divisions: USGeo::Division,
|
|
8
8
|
states: USGeo::State,
|
|
9
|
-
designated_market_areas: USGeo::DesignatedMarketArea,
|
|
10
9
|
combined_statistical_areas: USGeo::CombinedStatisticalArea,
|
|
11
10
|
core_based_statistical_areas: USGeo::CoreBasedStatisticalArea,
|
|
12
11
|
metropolitan_divisions: USGeo::MetropolitanDivision,
|
|
@@ -17,18 +16,24 @@ namespace :us_geo do
|
|
|
17
16
|
zctas: USGeo::Zcta,
|
|
18
17
|
zcta_counties: USGeo::ZctaCounty,
|
|
19
18
|
zcta_urban_areas: USGeo::ZctaUrbanArea,
|
|
19
|
+
zcta_county_subdivisions: USGeo::ZctaCountySubdivision,
|
|
20
20
|
zcta_places: USGeo::ZctaPlace,
|
|
21
21
|
urban_area_counties: USGeo::UrbanAreaCounty,
|
|
22
|
+
urban_area_county_subdivisions: USGeo::UrbanAreaCountySubdivision,
|
|
22
23
|
place_counties: USGeo::PlaceCounty
|
|
23
24
|
}
|
|
25
|
+
|
|
24
26
|
klasses.each do |name, klass|
|
|
25
27
|
desc "Import data for #{klass}"
|
|
26
28
|
task name => :environment do
|
|
27
29
|
t = Time.now
|
|
30
|
+
|
|
28
31
|
klass.load!
|
|
29
32
|
puts "Loaded #{klass.count} rows into #{klass.table_name} in #{(Time.now - t).round(1)}s"
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
|
|
34
|
+
removed_count = klass.removed.count
|
|
35
|
+
if removed_count > 0
|
|
36
|
+
puts " #{removed_count} previously imported records in #{klass.table_name} no longer exist in the current data source"
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
39
|
|
|
@@ -39,5 +44,41 @@ namespace :us_geo do
|
|
|
39
44
|
end
|
|
40
45
|
end
|
|
41
46
|
end
|
|
47
|
+
|
|
48
|
+
desc "List the number of records from previously imported data that no longer exists in the current data source"
|
|
49
|
+
task removed_counts: :environment do
|
|
50
|
+
klasses.each_value do |klass|
|
|
51
|
+
removed_count = klass.removed.count
|
|
52
|
+
puts "#{klass.table_name}: #{removed_count} previously imported records no longer exist in the current data source"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
desc "Dump the data for all records from previously imported data that no longer exists in the current data source to JSON"
|
|
57
|
+
task dump_removed: :environment do
|
|
58
|
+
require "json"
|
|
59
|
+
|
|
60
|
+
puts "{"
|
|
61
|
+
klasses.each_value do |klass|
|
|
62
|
+
puts " \"#{klass.table_name}\": ["
|
|
63
|
+
klass.removed.find_each do |record|
|
|
64
|
+
row_json JSON.dump(record.attributes.except("status", "updated_at"))
|
|
65
|
+
puts "#{row_json},"
|
|
66
|
+
end
|
|
67
|
+
puts "]"
|
|
68
|
+
end
|
|
69
|
+
puts "}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc "Remove all records from previously imported data that no longer exists in the current data source"
|
|
73
|
+
task cleanup: :environment do
|
|
74
|
+
klasses.each_value do |klass|
|
|
75
|
+
count = 0
|
|
76
|
+
klass.removed.find_each do |record|
|
|
77
|
+
count += 1
|
|
78
|
+
record.destroy
|
|
79
|
+
end
|
|
80
|
+
puts "Deleted #{count} removed records from #{klass.table_name}"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
42
83
|
end
|
|
43
84
|
end
|
data/lib/us_geo/area.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module USGeo
|
|
4
|
+
# This module is mixed into all models. Note that the area given for land and water
|
|
5
|
+
# is in square miles.
|
|
6
|
+
module Area
|
|
7
|
+
SQUARE_MILES_TO_KILOMETERS = 2.59
|
|
8
|
+
private_constant :SQUARE_MILES_TO_KILOMETERS
|
|
9
|
+
|
|
10
|
+
# @!attribute land_area
|
|
11
|
+
# @return [Float, nil] Land area in square miles.
|
|
12
|
+
|
|
13
|
+
# @!attribute water_area
|
|
14
|
+
# @return [Integer, nil] Water area in square miles.
|
|
15
|
+
|
|
16
|
+
# Total area of both land an water in square miles.
|
|
17
|
+
#
|
|
18
|
+
# @return [Float, nil]
|
|
19
|
+
def total_area
|
|
20
|
+
land_area.to_f + water_area.to_f if land_area
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# The fraction of the area that is composed of land instead of water.
|
|
24
|
+
#
|
|
25
|
+
# @return [Float, nil]
|
|
26
|
+
def percent_land
|
|
27
|
+
land_area / total_area if land_area
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Land area in square kilometers.
|
|
31
|
+
#
|
|
32
|
+
# @return [Float, nil]
|
|
33
|
+
def land_area_km
|
|
34
|
+
land_area * SQUARE_MILES_TO_KILOMETERS if land_area
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Water area in square kilometers.
|
|
38
|
+
#
|
|
39
|
+
# @return [Float, nil]
|
|
40
|
+
def water_area_km
|
|
41
|
+
water_area * SQUARE_MILES_TO_KILOMETERS if water_area
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/us_geo/base_record.rb
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "csv"
|
|
4
|
-
require "open-uri"
|
|
5
|
-
|
|
6
3
|
module USGeo
|
|
7
|
-
|
|
8
4
|
class LoadError < StandardError
|
|
9
5
|
end
|
|
10
6
|
|
|
11
7
|
# Base class that all models inherit from.
|
|
12
8
|
class BaseRecord < ::ActiveRecord::Base
|
|
13
|
-
|
|
14
9
|
self.abstract_class = true
|
|
15
10
|
self.table_name_prefix = "us_geo_"
|
|
16
11
|
|
|
@@ -23,7 +18,7 @@ module USGeo
|
|
|
23
18
|
scope :imported, -> { where(status: STATUS_IMPORTED) }
|
|
24
19
|
scope :removed, -> { where(status: STATUS_REMOVED) }
|
|
25
20
|
scope :manual, -> { where(status: STATUS_MANUAL) }
|
|
26
|
-
scope :not_removed, -> { where(status:
|
|
21
|
+
scope :not_removed, -> { where.not(status: STATUS_REMOVED) }
|
|
27
22
|
|
|
28
23
|
class << self
|
|
29
24
|
def load!(location = nil, gzipped: true)
|
|
@@ -61,11 +56,13 @@ module USGeo
|
|
|
61
56
|
end
|
|
62
57
|
|
|
63
58
|
def load_data_file(location, &block)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
require "open-uri"
|
|
60
|
+
require "csv"
|
|
61
|
+
|
|
62
|
+
file = if location.include?(":")
|
|
63
|
+
URI.parse(location).open(read_timeout: 5, open_timeout: 5)
|
|
67
64
|
else
|
|
68
|
-
|
|
65
|
+
File.open(location)
|
|
69
66
|
end
|
|
70
67
|
begin
|
|
71
68
|
rows = []
|
|
@@ -81,24 +78,33 @@ module USGeo
|
|
|
81
78
|
file.close if file && !file.closed?
|
|
82
79
|
end
|
|
83
80
|
end
|
|
84
|
-
|
|
85
|
-
# Convert square meters to square miles
|
|
86
|
-
def area_meters_to_miles(square_meters)
|
|
87
|
-
(square_meters.to_f / (1609.34 ** 2)).round(6)
|
|
88
|
-
end
|
|
89
81
|
end
|
|
90
82
|
|
|
83
|
+
# @!attribute status
|
|
84
|
+
# @return [Integer]
|
|
85
|
+
|
|
86
|
+
# @!attribute updated_at
|
|
87
|
+
# @return [Time]
|
|
88
|
+
|
|
89
|
+
# Return true if the record was imported from the data source distributed with the gem.
|
|
90
|
+
#
|
|
91
|
+
# @return [Boolean]
|
|
91
92
|
def imported?
|
|
92
93
|
status == STATUS_IMPORTED
|
|
93
94
|
end
|
|
94
95
|
|
|
96
|
+
# Return true if the record was removed from the data source distributed with the gem.
|
|
97
|
+
#
|
|
98
|
+
# @return [Boolean]
|
|
95
99
|
def removed?
|
|
96
100
|
status == STATUS_REMOVED
|
|
97
101
|
end
|
|
98
102
|
|
|
103
|
+
# Return true if the record was manually added to the database.
|
|
104
|
+
#
|
|
105
|
+
# @return [Boolean]
|
|
99
106
|
def manual?
|
|
100
107
|
status == STATUS_MANUAL
|
|
101
108
|
end
|
|
102
|
-
|
|
103
109
|
end
|
|
104
110
|
end
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module USGeo
|
|
4
|
-
|
|
5
4
|
# Combined statistical area (CSA) of multiple metropolitan areas with weak regional
|
|
6
5
|
# and economic connectoins between them.
|
|
7
6
|
class CombinedStatisticalArea < BaseRecord
|
|
8
|
-
|
|
9
|
-
include
|
|
7
|
+
include Population
|
|
8
|
+
include Area
|
|
10
9
|
|
|
11
10
|
self.primary_key = "geoid"
|
|
12
11
|
|
|
13
|
-
has_many :core_based_statistical_areas, foreign_key: :csa_geoid, inverse_of: :combined_statistical_area
|
|
12
|
+
has_many :core_based_statistical_areas, -> { not_removed }, foreign_key: :csa_geoid, inverse_of: :combined_statistical_area
|
|
13
|
+
has_many :counties, -> { not_removed }, through: :core_based_statistical_areas
|
|
14
|
+
has_many :metropolitan_divisions, -> { not_removed }, through: :core_based_statistical_areas
|
|
14
15
|
|
|
15
16
|
validates :geoid, length: {is: 3}
|
|
16
|
-
validates :name, length: {maximum: 60}
|
|
17
|
+
validates :name, presence: true, length: {maximum: 60}, uniqueness: true
|
|
17
18
|
validates :land_area, numericality: true, presence: true
|
|
18
19
|
validates :water_area, numericality: true, presence: true
|
|
19
20
|
validates :population, numericality: {only_integer: true}, presence: true
|
|
20
21
|
validates :housing_units, numericality: {only_integer: true}, presence: true
|
|
21
22
|
|
|
23
|
+
# @!attribute geoid
|
|
24
|
+
# @return [String] 3-digit code for the CSA.
|
|
25
|
+
|
|
26
|
+
# @!attribute name
|
|
27
|
+
# @return [String] Name of the CSA.
|
|
28
|
+
|
|
29
|
+
# @!attribute short_name
|
|
30
|
+
# @return [String] Short name of the CSA.
|
|
31
|
+
|
|
22
32
|
class << self
|
|
23
33
|
def load!(uri = nil)
|
|
24
34
|
location = data_uri(uri || "combined_statistical_areas.csv")
|
|
@@ -26,15 +36,15 @@ module USGeo
|
|
|
26
36
|
load_data_file(location) do |row|
|
|
27
37
|
load_record!(geoid: row["GEOID"]) do |record|
|
|
28
38
|
record.name = row["Name"]
|
|
39
|
+
record.short_name = row["Short Name"]
|
|
29
40
|
record.population = row["Population"]
|
|
30
41
|
record.housing_units = row["Housing Units"]
|
|
31
|
-
record.land_area =
|
|
32
|
-
record.water_area =
|
|
42
|
+
record.land_area = row["Land Area"]
|
|
43
|
+
record.water_area = row["Water Area"]
|
|
33
44
|
end
|
|
34
45
|
end
|
|
35
46
|
end
|
|
36
47
|
end
|
|
37
48
|
end
|
|
38
|
-
|
|
39
49
|
end
|
|
40
50
|
end
|
|
@@ -1,42 +1,55 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module USGeo
|
|
4
|
-
|
|
5
4
|
# Core based statistical area composed of one or more counties anchored by an urban center.
|
|
6
5
|
# Includes both metropolitan (population > 50,000) and micropolitan (population > 10,000
|
|
7
6
|
# but < 50,000) areas.
|
|
8
7
|
class CoreBasedStatisticalArea < BaseRecord
|
|
9
|
-
|
|
10
|
-
include
|
|
8
|
+
include Population
|
|
9
|
+
include Area
|
|
11
10
|
|
|
12
11
|
self.primary_key = "geoid"
|
|
13
12
|
self.store_full_sti_class = false
|
|
14
13
|
|
|
15
|
-
has_many :counties, foreign_key: :cbsa_geoid, inverse_of: :core_based_statistical_area
|
|
16
|
-
has_many :metropolitan_divisions, foreign_key: :cbsa_geoid, inverse_of: :core_based_statistical_area
|
|
14
|
+
has_many :counties, -> { not_removed }, foreign_key: :cbsa_geoid, inverse_of: :core_based_statistical_area
|
|
15
|
+
has_many :metropolitan_divisions, -> { not_removed }, foreign_key: :cbsa_geoid, inverse_of: :core_based_statistical_area
|
|
16
|
+
has_many :zctas, -> { not_removed }, through: :counties
|
|
17
|
+
has_many :places, -> { not_removed }, through: :counties
|
|
18
|
+
|
|
17
19
|
belongs_to :combined_statistical_area, foreign_key: :csa_geoid, optional: true, inverse_of: :core_based_statistical_areas
|
|
18
20
|
|
|
19
21
|
validates :geoid, length: {is: 5}
|
|
20
|
-
validates :name, length: {maximum: 60}
|
|
22
|
+
validates :name, presence: true, length: {maximum: 60}, uniqueness: true
|
|
23
|
+
validates :short_name, presence: true, length: {maximum: 60}, uniqueness: true
|
|
21
24
|
validates :land_area, numericality: true, presence: true
|
|
22
25
|
validates :water_area, numericality: true, presence: true
|
|
23
26
|
validates :population, numericality: {only_integer: true}, presence: true
|
|
24
27
|
validates :housing_units, numericality: {only_integer: true}, presence: true
|
|
25
28
|
|
|
29
|
+
# @!attribute geoid
|
|
30
|
+
# @return [String] 5-digit code for the CBSA.
|
|
31
|
+
|
|
32
|
+
# @!attribute name
|
|
33
|
+
# @return [String] Name of the CBSA.
|
|
34
|
+
|
|
35
|
+
# @!attribute short_name
|
|
36
|
+
# @return [String] Short name of the CBSA.
|
|
37
|
+
|
|
26
38
|
class << self
|
|
27
39
|
def load!(uri = nil)
|
|
28
40
|
location = data_uri(uri || "core_based_statistical_areas.csv")
|
|
29
|
-
|
|
41
|
+
|
|
30
42
|
import! do
|
|
31
43
|
load_data_file(location) do |row|
|
|
32
44
|
load_record!(geoid: row["GEOID"]) do |record|
|
|
33
|
-
record.type = (row["Population"].to_i >= 50_000 ? "MetropolitanArea" : "MicropolitanArea")
|
|
45
|
+
record.type = ((row["Population"].to_i >= 50_000) ? "MetropolitanArea" : "MicropolitanArea")
|
|
34
46
|
record.name = row["Name"]
|
|
47
|
+
record.short_name = row["Short Name"]
|
|
35
48
|
record.csa_geoid = row["CSA"]
|
|
36
49
|
record.population = row["Population"]
|
|
37
50
|
record.housing_units = row["Housing Units"]
|
|
38
|
-
record.land_area =
|
|
39
|
-
record.water_area =
|
|
51
|
+
record.land_area = row["Land Area"]
|
|
52
|
+
record.water_area = row["Water Area"]
|
|
40
53
|
record.lat = row["Latitude"]
|
|
41
54
|
record.lng = row["Longitude"]
|
|
42
55
|
end
|
|
@@ -48,10 +61,9 @@ module USGeo
|
|
|
48
61
|
def metropolitan?
|
|
49
62
|
raise NotImplementedError
|
|
50
63
|
end
|
|
51
|
-
|
|
64
|
+
|
|
52
65
|
def micropolitan?
|
|
53
66
|
raise NotImplementedError
|
|
54
67
|
end
|
|
55
|
-
|
|
56
68
|
end
|
|
57
69
|
end
|