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
@@ -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
|