concensus 0.0.5
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.
- data/.gitignore +16 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +41 -0
- data/LICENSE +22 -0
- data/README.md +47 -0
- data/Rakefile +2 -0
- data/concensus.gemspec +25 -0
- data/lib/concensus/configuration.rb +45 -0
- data/lib/concensus/congressional.rb +16 -0
- data/lib/concensus/county.rb +16 -0
- data/lib/concensus/place.rb +16 -0
- data/lib/concensus/resource.rb +117 -0
- data/lib/concensus/school.rb +44 -0
- data/lib/concensus/state.rb +20 -0
- data/lib/concensus/state_legislative.rb +31 -0
- data/lib/concensus/version.rb +3 -0
- data/lib/concensus.rb +16 -0
- data/lib/geo_ruby/simple_features.rb +29 -0
- data/spec/concensus/accuracy_spec.rb +21 -0
- data/spec/concensus/configuration_spec.rb +37 -0
- data/spec/concensus/congressional_spec.rb +15 -0
- data/spec/concensus/county_spec.rb +15 -0
- data/spec/concensus/place_spec.rb +15 -0
- data/spec/concensus/school_spec.rb +37 -0
- data/spec/concensus/state_legislative_spec.rb +26 -0
- data/spec/concensus/state_spec.rb +11 -0
- metadata +168 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
concensus (0.0.5)
|
5
|
+
activesupport
|
6
|
+
dbf
|
7
|
+
georuby
|
8
|
+
rspec
|
9
|
+
rubyzip
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
activesupport (3.2.6)
|
15
|
+
i18n (~> 0.6)
|
16
|
+
multi_json (~> 1.0)
|
17
|
+
dbf (1.7.5)
|
18
|
+
diff-lcs (1.1.3)
|
19
|
+
georuby (1.9.7)
|
20
|
+
i18n (0.6.0)
|
21
|
+
multi_json (1.3.6)
|
22
|
+
redcarpet (2.1.1)
|
23
|
+
rspec (2.10.0)
|
24
|
+
rspec-core (~> 2.10.0)
|
25
|
+
rspec-expectations (~> 2.10.0)
|
26
|
+
rspec-mocks (~> 2.10.0)
|
27
|
+
rspec-core (2.10.1)
|
28
|
+
rspec-expectations (2.10.0)
|
29
|
+
diff-lcs (~> 1.1.3)
|
30
|
+
rspec-mocks (2.10.1)
|
31
|
+
rubyzip (0.9.9)
|
32
|
+
yard (0.8.2.1)
|
33
|
+
|
34
|
+
PLATFORMS
|
35
|
+
ruby
|
36
|
+
|
37
|
+
DEPENDENCIES
|
38
|
+
concensus!
|
39
|
+
redcarpet
|
40
|
+
rspec
|
41
|
+
yard
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 adamjacobbecker
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Concensus
|
2
|
+
|
3
|
+
Concensus is a gem for reading the United States Census Bureau's TIGER/Line Shapefiles.
|
4
|
+
|
5
|
+
It uses the [georuby](http://rubygems.org/gems/georuby) gem to convert the shapefiles, which leaves you with access to all of the methods in the [georuby API](http://www.ruby-doc.org/gems/docs/g/georuby-1.9.7/GeoRuby/SimpleFeatures/MultiPolygon.html).
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
gem 'concensus'
|
10
|
+
|
11
|
+
|
12
|
+
## Use
|
13
|
+
|
14
|
+
Concensus::Place.find("CA", "Berkeley")
|
15
|
+
=> #<Concensus::Resource>
|
16
|
+
|
17
|
+
Concensus::Place.find_all("CA")
|
18
|
+
=> [#<Concensus::Resource>, #<Concensus::Resource>, etc...]
|
19
|
+
|
20
|
+
california = Concensus::State.find("CA")
|
21
|
+
|
22
|
+
california.geometry
|
23
|
+
=> #<GeoRuby::SimpleFeatures::MultiPolygon>
|
24
|
+
|
25
|
+
california.geometry.to_array
|
26
|
+
=> [[[-119.000932, 33.535895], [-119.000932, 33.535823], [-118.997845, 33.534199], [-118.994453, 33.532711], [-118.992796, 33.531849], [-118.990046, 33.530288999999996], [-118.986199, 33.527425], ...], ...]
|
27
|
+
|
28
|
+
california.geometry.to_array[0]
|
29
|
+
=> [[-119.000932, 33.535895], [-119.000932, 33.535823], ... ]
|
30
|
+
|
31
|
+
|
32
|
+
### Full Documentation
|
33
|
+
[http://www.googl.com]()
|
34
|
+
|
35
|
+
### Notes
|
36
|
+
|
37
|
+
Some of the .zip files downloaded are quite large, so this gem requires temporary storage to unzip and cache the downloaded files. By default, we store these in `~/.concensus/tmp/`.
|
38
|
+
|
39
|
+
If you're using Rails, you'll probably want to create an initializer with `Concensus.configure { |c| c.tmp_dir = "#{Rails.root}/tmp/concensus/" }`. This way, you can use Concensus with the (very temporary) writable storage on Heroku.
|
40
|
+
|
41
|
+
#### Todo
|
42
|
+
|
43
|
+
- Add support for switching Census year (already started, not fully implemented yet.)
|
44
|
+
- Add more geographic areas, we only have a small bit of [what's available](http://www.census.gov/geo/www/tiger/tgrshp2010/availability.html).
|
45
|
+
- Add support for storing downloaded and uncompressed .zips on S3. (Heroku has no persistent writable file storage.)
|
46
|
+
|
47
|
+
**Support development by sending links to sick house music mixes:** [@AdamJacobBecker](http://www.twitter.com/AdamJacobBecker)
|
data/Rakefile
ADDED
data/concensus.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/concensus/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["adamjacobbecker"]
|
6
|
+
gem.email = ["ad@mbecker.cc"]
|
7
|
+
gem.description = %q{"A small tool for reading United States Census TIGER/Line Shapefiles."}
|
8
|
+
gem.summary = %q{"Converts U.S. Census Shapes to RGeo format."}
|
9
|
+
gem.homepage = "https://github.com/adamjacobbecker/concensus"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "concensus"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Concensus::VERSION
|
17
|
+
|
18
|
+
%w{rspec yard redcarpet}.each do |x|
|
19
|
+
gem.add_development_dependency x
|
20
|
+
end
|
21
|
+
|
22
|
+
%w{rspec activesupport rubyzip georuby dbf}.each do |x|
|
23
|
+
gem.add_dependency x
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Concensus
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :year, :census_state_ids
|
4
|
+
attr_reader :tmp_dir, :default_tmp_dir
|
5
|
+
|
6
|
+
# Temporary directory for storing .zip files and their contents.
|
7
|
+
# It's best if this directory persists as a "cache" of sorts, so
|
8
|
+
# that we're not hitting the Census server over and over.
|
9
|
+
#
|
10
|
+
# On Heroku, set this to #{RAILS_ROOT}/tmp, which is Heroku's
|
11
|
+
# only writable storage.
|
12
|
+
def tmp_dir=(x)
|
13
|
+
@tmp_dir = x
|
14
|
+
FileUtils.mkdir_p(@tmp_dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
# This will become useful once we can switch years...
|
18
|
+
def root_url
|
19
|
+
"http://www2.census.gov/geo/tiger/TIGER#{@year}/"
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@year = 2010
|
24
|
+
|
25
|
+
@tmp_dir = @default_tmp_dir = "#{Dir.home()}/.concensus/tmp/"
|
26
|
+
FileUtils.mkdir_p(@tmp_dir)
|
27
|
+
|
28
|
+
# Not really sure what the Census' IT department was going for with this number system.
|
29
|
+
@census_state_ids = { "AL"=>"01","AK"=>"02","AZ"=>"04","AR"=>"05","CA"=>"06","CO"=>"08","CT"=>"09","DE"=>"10","DC"=>"11","FL"=>"12","GA"=>"13","HI"=>"15","ID"=>"16","IL"=>"17","IN"=>"18","IA"=>"19","KS"=>"20","KY"=>"21","LA"=>"22","ME"=>"23","MD"=>"24","MA"=>"25","MI"=>"26","MN"=>"27","MS"=>"28","MO"=>"29","MT"=>"30","NE"=>"31","NV"=>"32","NH"=>"33","NJ"=>"34","NM"=>"35","NY"=>"36","NC"=>"37","ND"=>"38","OH"=>"39","OK"=>"40","OR"=>"41","PA"=>"42","RI"=>"44","SC"=>"45","SD"=>"46","TN"=>"47","TX"=>"48","UT"=>"49","VT"=>"50","VA"=>"51","WA"=>"53","WV"=>"54","WI"=>"55","WY"=>"56","AS"=>"60","GU"=>"66","MP"=>"69","PR"=>"72","VI"=>"78" }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
attr_accessor :configuration
|
35
|
+
|
36
|
+
def configuration
|
37
|
+
@configuration = Configuration.new if @configuration.nil?
|
38
|
+
@configuration
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.configure
|
43
|
+
yield(configuration)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Concensus
|
2
|
+
class Congressional < Resource
|
3
|
+
|
4
|
+
# @return [Concensus::Resource] matched congressional district
|
5
|
+
def self.find(state, name = nil)
|
6
|
+
shp_file_path = get_and_unzip("CD/111/tl_2010_#{state_code_to_id(state)}_cd111.zip")
|
7
|
+
return process_find(shp_file_path, "NAMELSAD10", state, name)
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Array] array of all congressional districts for a state
|
11
|
+
def self.find_all(state)
|
12
|
+
find(state)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Concensus
|
2
|
+
class County < Resource
|
3
|
+
|
4
|
+
# @return [Concensus::Resource] matched county
|
5
|
+
def self.find(state, name = nil)
|
6
|
+
shp_file_path = get_and_unzip("COUNTY/2010/tl_2010_#{state_code_to_id(state)}_county10.zip")
|
7
|
+
return process_find(shp_file_path, "NAME10", state, name)
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Array] all counties for a state
|
11
|
+
def self.find_all(state)
|
12
|
+
find(state)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Concensus
|
2
|
+
class Place < Resource
|
3
|
+
|
4
|
+
# @return [Concensus::Resource] matched place
|
5
|
+
def self.find(state, name = nil)
|
6
|
+
shp_file_path = get_and_unzip("PLACE/2010/tl_2010_#{state_code_to_id(state)}_place10.zip")
|
7
|
+
return process_find(shp_file_path, "NAME10", state, name)
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Array] all places for a state
|
11
|
+
def self.find_all(state)
|
12
|
+
find(state)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "zip/zip"
|
2
|
+
require "geo_ruby"
|
3
|
+
require "geo_ruby/shp"
|
4
|
+
require "open-uri"
|
5
|
+
|
6
|
+
module Concensus
|
7
|
+
class Resource
|
8
|
+
|
9
|
+
# @return [MultiPolygon] georuby geometry object
|
10
|
+
attr_accessor :geometry
|
11
|
+
|
12
|
+
# @return [String] this resource's name in the shpfile metadata
|
13
|
+
attr_accessor :name
|
14
|
+
|
15
|
+
# @return [String] the state this resource belongs to, if applicable
|
16
|
+
attr_accessor :state
|
17
|
+
|
18
|
+
# @return [Fixnum] this resource's census year
|
19
|
+
attr_accessor :year
|
20
|
+
|
21
|
+
def initialize(name, geometry, state)
|
22
|
+
@name = name
|
23
|
+
@geometry = geometry
|
24
|
+
@state = state
|
25
|
+
@year = Concensus::configuration.year
|
26
|
+
end
|
27
|
+
|
28
|
+
# Checks for census zipfile in temporary storage. If not there, downloads it.
|
29
|
+
# Then, checks for unzipped files in temporary storage. If not there, unzips the archive.
|
30
|
+
#
|
31
|
+
# @return [String] path to shpfile in temporary storage
|
32
|
+
def self.get_and_unzip(uri)
|
33
|
+
safe_filename = uri.gsub("/", "_").gsub(".zip", "")
|
34
|
+
zipped_file_path = "#{Concensus::configuration.tmp_dir}#{safe_filename}.zip"
|
35
|
+
|
36
|
+
if !File.exists?(zipped_file_path)
|
37
|
+
zipped_file = File.new(zipped_file_path, "wb")
|
38
|
+
ext_file = open(Concensus::configuration.root_url + uri)
|
39
|
+
zipped_file.write(ext_file.read)
|
40
|
+
end
|
41
|
+
|
42
|
+
if !already_unzipped?(zipped_file_path)
|
43
|
+
unzipped_files = Zip::ZipFile.open(zipped_file_path)
|
44
|
+
|
45
|
+
unzipped_files.each do |x|
|
46
|
+
file = File.new(Concensus::configuration.tmp_dir + safe_filename + file_extension(x.to_s), "wb")
|
47
|
+
file.write(x.get_input_stream.read)
|
48
|
+
file.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
return "#{Concensus::configuration.tmp_dir}#{safe_filename}.shp"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Converts the shpfile to a georuby object.
|
56
|
+
#
|
57
|
+
# If we're searching for a specific region in the shpfile,
|
58
|
+
# we find it by iterating over each region and matching
|
59
|
+
# by metadata. We return the first one we find.
|
60
|
+
#
|
61
|
+
# @return [Array] returns array if we're looking for mulitple regions
|
62
|
+
# @return [Resource] returns resource if we're looking for a specific region
|
63
|
+
def self.process_find(shp_file_path, identifier, state, name = nil)
|
64
|
+
|
65
|
+
# Prevent annoying georuby error messages
|
66
|
+
previous_stderr, $stderr = $stderr, StringIO.new
|
67
|
+
|
68
|
+
if name
|
69
|
+
GeoRuby::Shp4r::ShpFile.open(shp_file_path) do |shp|
|
70
|
+
matched_shape = shp.find {|x| x.data[identifier].match(name) }
|
71
|
+
raise StandardError if !matched_shape
|
72
|
+
return Resource.new(matched_shape.data[identifier], matched_shape.geometry, state)
|
73
|
+
end
|
74
|
+
else
|
75
|
+
places = []
|
76
|
+
GeoRuby::Shp4r::ShpFile.open(shp_file_path).each do |shp|
|
77
|
+
places << Resource.new(shp.data[identifier], shp.geometry, state)
|
78
|
+
end
|
79
|
+
return places
|
80
|
+
end
|
81
|
+
|
82
|
+
# Restore previous value of stderr
|
83
|
+
$stderr.string
|
84
|
+
$stderr = previous_stderr
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
# Converts a state code, like "CA", to the US Census Bureau's numerical identifier.
|
89
|
+
# @param [String] two-letter state code
|
90
|
+
# @return [Fixnum] numerical census state identifier
|
91
|
+
def self.state_code_to_id(state_code)
|
92
|
+
Concensus::configuration.census_state_ids[state_code]
|
93
|
+
end
|
94
|
+
|
95
|
+
# @return [Boolean] true if the zip's files are found in
|
96
|
+
# temporary storage
|
97
|
+
def self.already_unzipped?(zipped_file_path)
|
98
|
+
file_path_without_extension = filename_without_extension(zipped_file_path)
|
99
|
+
File.exists?("#{file_path_without_extension}.shp") &&
|
100
|
+
File.exists?("#{file_path_without_extension}.dbf") &&
|
101
|
+
File.exists?("#{file_path_without_extension}.shx")
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param [String] filename
|
105
|
+
# @return [String]filename with the extension stripped.
|
106
|
+
def self.filename_without_extension(filename)
|
107
|
+
filename.gsub(/\.[a-z]*$/, "")
|
108
|
+
end
|
109
|
+
|
110
|
+
# @param [String] filename
|
111
|
+
# @return [String] file's extension.
|
112
|
+
def self.file_extension(filename)
|
113
|
+
filename[/\.[a-z]*$/]
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Concensus
|
2
|
+
class School < Resource
|
3
|
+
|
4
|
+
class Elementary < School
|
5
|
+
# @return [Concensus::Resource] matched elementary school district
|
6
|
+
def self.find(state, name = nil)
|
7
|
+
shp_file_path = get_and_unzip("ELSD/2010/tl_2010_#{state_code_to_id(state)}_elsd10.zip")
|
8
|
+
return process_find(shp_file_path, "NAME10", state, name)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Array] all elementary school districts for a state
|
12
|
+
def self.find_all(state)
|
13
|
+
find(state)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Secondary < School
|
18
|
+
# @return [Concensus::Resource] matched secondary school district
|
19
|
+
def self.find(state, name = nil)
|
20
|
+
shp_file_path = get_and_unzip("SCSD/2010/tl_2010_#{state_code_to_id(state)}_scsd10.zip")
|
21
|
+
return process_find(shp_file_path, "NAME10", state, name)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Array] all secondary school districts for a state
|
25
|
+
def self.find_all(state)
|
26
|
+
find(state)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Unified < School
|
31
|
+
# @return [Concensus::Resource] matched unified school district
|
32
|
+
def self.find(state, name = nil)
|
33
|
+
shp_file_path = get_and_unzip("UNSD/2010/tl_2010_#{state_code_to_id(state)}_unsd10.zip")
|
34
|
+
return process_find(shp_file_path, "NAME10", state, name)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Array] all unified school districts for a state
|
38
|
+
def self.find_all(state)
|
39
|
+
find(state)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Concensus
|
2
|
+
class State < Resource
|
3
|
+
|
4
|
+
# @return [Concensus::Resource] matched state
|
5
|
+
def self.find(state)
|
6
|
+
shp_file_path = get_and_unzip("STATE/2010/tl_2010_#{state_code_to_id(state)}_state10.zip")
|
7
|
+
return process_find(shp_file_path, "NAME10", state)[0]
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Array] all states
|
11
|
+
def self.find_all
|
12
|
+
shapes = []
|
13
|
+
Concensus::configuration.census_state_ids.each do |state_code, _|
|
14
|
+
shapes << find(state_code)
|
15
|
+
end
|
16
|
+
return shapes
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Concensus
|
2
|
+
class StateLegislative < Resource
|
3
|
+
|
4
|
+
class Upper < StateLegislative
|
5
|
+
# @return [Concensus::Resource] matched state upper legislative district
|
6
|
+
def self.find(state, name = nil)
|
7
|
+
shp_file_path = get_and_unzip("SLDU/2010/tl_2010_#{state_code_to_id(state)}_sldu10.zip")
|
8
|
+
return process_find(shp_file_path, "NAMELSAD10", state, name)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Array] all state's upper legislative districts
|
12
|
+
def self.find_all(state)
|
13
|
+
find(state)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Lower < StateLegislative
|
18
|
+
# @return [Concensus::Resource] matched state lower legislative district
|
19
|
+
def self.find(state, name = nil)
|
20
|
+
shp_file_path = get_and_unzip("SLDL/2010/tl_2010_#{state_code_to_id(state)}_sldl10.zip")
|
21
|
+
return process_find(shp_file_path, "NAMELSAD10", state, name)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Array] all state's lower legislative district
|
25
|
+
def self.find_all(state)
|
26
|
+
find(state)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/concensus.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "concensus/version"
|
2
|
+
require "concensus/configuration"
|
3
|
+
require "concensus/resource"
|
4
|
+
require "concensus/place"
|
5
|
+
require "concensus/county"
|
6
|
+
require "concensus/state"
|
7
|
+
require "concensus/state_legislative"
|
8
|
+
require "concensus/congressional"
|
9
|
+
require "concensus/school"
|
10
|
+
require "geo_ruby/simple_features"
|
11
|
+
require "active_support"
|
12
|
+
require "zip/zip"
|
13
|
+
|
14
|
+
module Concensus
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Monkeypatches GeoRuby to add a couple class methods.
|
2
|
+
module GeoRuby
|
3
|
+
module SimpleFeatures
|
4
|
+
class MultiPolygon
|
5
|
+
# A shortcut for grabbing an array of coordinates from GeoRuby's MultiPolygon.
|
6
|
+
# @return [Array] an array of polygons, each one an array of coordinate pairs
|
7
|
+
def to_array
|
8
|
+
coord_array = self.as_json[:coordinates]
|
9
|
+
|
10
|
+
## Fixes weird, unnecessary extra array
|
11
|
+
0.upto(coord_array.count - 1).each do |i|
|
12
|
+
coord_array[i] = coord_array[i][0]
|
13
|
+
end
|
14
|
+
|
15
|
+
return coord_array
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [GeoRuby::SimpleFeatures::Point] GeoRuby Point object
|
19
|
+
# @return [Boolean] true if any of the Polygon's shapes contain this point
|
20
|
+
def contains_point?(point)
|
21
|
+
self.each do |shape|
|
22
|
+
return true if shape.contains_point?(point)
|
23
|
+
end
|
24
|
+
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
|
5
|
+
describe "accuracy" do
|
6
|
+
it "should find correct the polygon for berkeley" do
|
7
|
+
berkeley = GeoRuby::SimpleFeatures::Point.from_x_y(-122.2728, 37.8717)
|
8
|
+
not_berkeley = GeoRuby::SimpleFeatures::Point.from_x_y(-122.2728, 30.8717)
|
9
|
+
Concensus::Place.find("CA", "Berkeley").geometry.contains_point?(berkeley).should be_true
|
10
|
+
Concensus::Place.find("CA", "Berkeley").geometry.contains_point?(not_berkeley).should be_false
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should find correct the polygon for santa cruz" do
|
14
|
+
santa_cruz = GeoRuby::SimpleFeatures::Point.from_x_y(-122.0297, 36.9742)
|
15
|
+
not_santa_cruz = GeoRuby::SimpleFeatures::Point.from_x_y(-125.0297, 36.9742)
|
16
|
+
Concensus::Place.find("CA", "Santa Cruz").geometry.contains_point?(santa_cruz).should be_true
|
17
|
+
Concensus::Place.find("CA", "Santa Cruz").geometry.contains_point?(not_santa_cruz).should be_false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
|
5
|
+
describe "configuration" do
|
6
|
+
it "should have a root url" do
|
7
|
+
Concensus::configuration.root_url.should_not be_empty
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "should be able to manually set the tmp file" do
|
11
|
+
before { Concensus::configuration.tmp_dir = "tmp/concensustest/" }
|
12
|
+
after do
|
13
|
+
Dir::unlink(Concensus::configuration.tmp_dir)
|
14
|
+
Concensus::configuration.tmp_dir = Concensus::configuration.default_tmp_dir
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should create the new temp dir" do
|
18
|
+
File.directory?("tmp/concensustest/").should == true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "default year should be 2010" do
|
23
|
+
Concensus::configuration.year.should == 2010
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "should be able to manually set the year" do
|
27
|
+
before { Concensus::configuration.year = 2000 }
|
28
|
+
after { Concensus::configuration.year = 2010 }
|
29
|
+
|
30
|
+
it "should be updated" do
|
31
|
+
Concensus::configuration.year.should == 2000
|
32
|
+
Concensus::configuration.root_url.should match(/2000/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
describe "congressional districts" do
|
5
|
+
|
6
|
+
it "should be able to find a congressional district district for a state" do
|
7
|
+
Concensus::Congressional.find("CA", "13").should be_instance_of(Concensus::Resource)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be able to find all upper legislative districts for a state" do
|
11
|
+
Concensus::Congressional.find_all("CA").should be_instance_of(Array)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
describe "counties" do
|
5
|
+
|
6
|
+
it "should be able to find all counties for a state" do
|
7
|
+
Concensus::County.find_all("CA").should be_instance_of(Array)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be able to find one county for a state" do
|
11
|
+
Concensus::County.find("CA", "Alameda").should be_instance_of(Concensus::Resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
describe "places" do
|
5
|
+
|
6
|
+
it "should be able to find all places for a state" do
|
7
|
+
Concensus::Place.find_all("CA").should be_instance_of(Array)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be able to find one places for a state" do
|
11
|
+
Concensus::Place.find("CA", "Berkeley").should be_instance_of(Concensus::Resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
describe "school districts" do
|
5
|
+
|
6
|
+
describe "elementary" do
|
7
|
+
it "should be able to find an elementary school district for a state" do
|
8
|
+
Concensus::School::Elementary.find("AZ", "San Fernando").should be_instance_of(Concensus::Resource)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to find all elementary school districts for a state" do
|
12
|
+
Concensus::School::Elementary.find_all("AZ").should be_instance_of(Array)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "elementary" do
|
17
|
+
it "should be able to find a secondary school district for a state" do
|
18
|
+
Concensus::School::Secondary.find("AZ", "Tempe Union").should be_instance_of(Concensus::Resource)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to find all secondary school districts for a state" do
|
22
|
+
Concensus::School::Secondary.find_all("AZ").should be_instance_of(Array)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "unified" do
|
27
|
+
it "should be able to find a unified school district for a state" do
|
28
|
+
Concensus::School::Unified.find("AZ", "Chandler").should be_instance_of(Concensus::Resource)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be able to find all unified school districts for a state" do
|
32
|
+
Concensus::School::Unified.find_all("AZ").should be_instance_of(Array)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'concensus'
|
2
|
+
|
3
|
+
describe Concensus do
|
4
|
+
describe "state legislative districts" do
|
5
|
+
|
6
|
+
describe "upper" do
|
7
|
+
it "should be able to find an upper legislative district for a state" do
|
8
|
+
Concensus::StateLegislative::Upper.find("CA", "13").should be_instance_of(Concensus::Resource)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to find all upper legislative districts for a state" do
|
12
|
+
Concensus::StateLegislative::Upper.find_all("CA").should be_instance_of(Array)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "lower" do
|
17
|
+
it "should be able to find a lower legislative district for a state" do
|
18
|
+
Concensus::StateLegislative::Lower.find("CA", "13").should be_instance_of(Concensus::Resource)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to find all lower legislative districts for a state" do
|
22
|
+
Concensus::StateLegislative::Lower.find_all("CA").should be_instance_of(Array)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: concensus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- adamjacobbecker
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70135306169280 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70135306169280
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yard
|
27
|
+
requirement: &70135306168460 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70135306168460
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: redcarpet
|
38
|
+
requirement: &70135306167620 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70135306167620
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70135306166780 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70135306166780
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: activesupport
|
60
|
+
requirement: &70135306166200 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70135306166200
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubyzip
|
71
|
+
requirement: &70135306165640 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70135306165640
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: georuby
|
82
|
+
requirement: &70135306164940 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70135306164940
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: dbf
|
93
|
+
requirement: &70135306164140 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70135306164140
|
102
|
+
description: ! '"A small tool for reading United States Census TIGER/Line Shapefiles."'
|
103
|
+
email:
|
104
|
+
- ad@mbecker.cc
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- .gitignore
|
110
|
+
- Gemfile
|
111
|
+
- Gemfile.lock
|
112
|
+
- LICENSE
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- concensus.gemspec
|
116
|
+
- lib/concensus.rb
|
117
|
+
- lib/concensus/configuration.rb
|
118
|
+
- lib/concensus/congressional.rb
|
119
|
+
- lib/concensus/county.rb
|
120
|
+
- lib/concensus/place.rb
|
121
|
+
- lib/concensus/resource.rb
|
122
|
+
- lib/concensus/school.rb
|
123
|
+
- lib/concensus/state.rb
|
124
|
+
- lib/concensus/state_legislative.rb
|
125
|
+
- lib/concensus/version.rb
|
126
|
+
- lib/geo_ruby/simple_features.rb
|
127
|
+
- spec/concensus/accuracy_spec.rb
|
128
|
+
- spec/concensus/configuration_spec.rb
|
129
|
+
- spec/concensus/congressional_spec.rb
|
130
|
+
- spec/concensus/county_spec.rb
|
131
|
+
- spec/concensus/place_spec.rb
|
132
|
+
- spec/concensus/school_spec.rb
|
133
|
+
- spec/concensus/state_legislative_spec.rb
|
134
|
+
- spec/concensus/state_spec.rb
|
135
|
+
homepage: https://github.com/adamjacobbecker/concensus
|
136
|
+
licenses: []
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
none: false
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 1.8.15
|
156
|
+
signing_key:
|
157
|
+
specification_version: 3
|
158
|
+
summary: ! '"Converts U.S. Census Shapes to RGeo format."'
|
159
|
+
test_files:
|
160
|
+
- spec/concensus/accuracy_spec.rb
|
161
|
+
- spec/concensus/configuration_spec.rb
|
162
|
+
- spec/concensus/congressional_spec.rb
|
163
|
+
- spec/concensus/county_spec.rb
|
164
|
+
- spec/concensus/place_spec.rb
|
165
|
+
- spec/concensus/school_spec.rb
|
166
|
+
- spec/concensus/state_legislative_spec.rb
|
167
|
+
- spec/concensus/state_spec.rb
|
168
|
+
has_rdoc:
|