Skip to content

Commit

Permalink
Implement GeoRuby for parsing WKT shapes
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanrolds committed May 13, 2019
1 parent 275236c commit ad1ab62
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 59 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.3.3
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ gem 'actionpack-page_caching'
gem 'whenever', require: false
gem 'geoip'
gem 'ipaddress'
gem 'georuby', '~> 2.5', '>= 2.5.2'

group :production do
gem 'unicorn'
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ GEM
sass (>= 3.2)
geocoder (1.5.1)
geoip (1.6.4)
georuby (2.5.2)
globalid (0.4.2)
activesupport (>= 4.2.0)
google-analytics-rails (1.1.0)
Expand Down Expand Up @@ -278,6 +279,7 @@ DEPENDENCIES
font-awesome-sass (~> 4.5.0)
geocoder
geoip
georuby (~> 2.5, >= 2.5.2)
google-analytics-rails (= 1.1.0)
ipaddress
jbuilder (~> 2.0)
Expand Down
2 changes: 0 additions & 2 deletions app/models/census_boundary.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
class CensusBoundary < ActiveRecord::Base

serialize :bounds, Array

end
34 changes: 17 additions & 17 deletions app/models/submission.rb
Original file line number Diff line number Diff line change
Expand Up @@ -232,23 +232,23 @@ def self.set_mapbox_census_data(params, data=[])
end

feature = {
'type': 'Feature',
'properties': {
'title': census_code,
'count': number_with_delimiter(submissions.length, delimiter: ','),
'median_speed': median_speed,
'fast_speed': '%.2f' % submissions.map(&:"#{attribute_name}").compact.max.to_f,
'fillColor': params['type'] == 'stats' && set_stats_color(submissions.count) || set_color(median_speed),
'fillOpacity': 0.5,
'weight': 2,
'opacity': 1,
'color': params['type'] == 'stats' && set_stats_color(submissions.count) || set_color(median_speed),
},
'geometry': {
'type': 'Polygon',
'coordinates': census_coordinates,
}
}
'type': 'Feature',
'properties': {
'title': census_code,
'count': number_with_delimiter(submissions.length, delimiter: ','),
'median_speed': median_speed,
'fast_speed': '%.2f' % submissions.map(&:"#{attribute_name}").compact.max.to_f,
'fillColor': params['type'] == 'stats' && set_stats_color(submissions.count) || set_color(median_speed),
'fillOpacity': 0.5,
'weight': 2,
'opacity': 1,
'color': params['type'] == 'stats' && set_stats_color(submissions.count) || set_color(median_speed),
},
'geometry': {
'type': 'Polygon',
'coordinates': census_coordinates,
}
}

data << feature
end
Expand Down
27 changes: 6 additions & 21 deletions lib/tasks/census_tract_boundaries.rake
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'mechanize'
require 'json'
require 'rake'
require 'georuby'

task :populate_census_tracts => [:environment] do
puts "Right now we're only including census tracts that overlap with Lane County, OR."
Expand All @@ -9,7 +10,7 @@ task :populate_census_tracts => [:environment] do
add_count = 0

# read in the JSON line by line
IO.foreach("/suyc/db/data/cb_2016_us_census_tracts") { |line|
IO.foreach("/suyc/data/cb_2016_us_census_tracts.json") { |line|

# parse the line
data = JSON.parse(line)
Expand All @@ -23,32 +24,16 @@ task :populate_census_tracts => [:environment] do
# if it's already in ZipBoundary, ignore it
next if CensusBoundary.where(name: data["TRACTCE"]).present?

# clean up the lat long pairs
bounds = clean_bounds(data["tract_polygons"])
# get polygon
polygon = GeoRuby::SimpleFeatures::MultiPolygon.from_ewkt(data["tract_polygons"])

# otherwise, create a new record
CensusBoundary.create(name: data["TRACTCE"], geo_id: data["GEOID"], bounds: bounds)
CensusBoundary.create(name: data["TRACTCE"], geo_id: data["GEOID"], bounds: polygon.to_coordinates())

# increment the count
add_count += 1
}

puts "Added #{add_count} census tracts."

end

def clean_bounds(b)
if b.start_with?('MULTIPOLYGON')
#cords = b.gsub('MULTIPOLYGON(((', '').gsub(')))', '')
#cords = [cords.split(',').collect{|c| c.split(" ").map(&:to_f).reverse()}]

#puts cords
return [[]]
else
cords = b.gsub('POLYGON((', '').gsub('))', '')
cords = [cords.split(',').collect{|c| c.split(" ").map(&:to_f).reverse()}]

puts cords
return cords
end
end
end
27 changes: 8 additions & 19 deletions lib/tasks/create_zip_boundaries.rake
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require 'mechanize'
require 'json'
require 'rake'
require 'georuby'
require 'geo_ruby/ewk'


task :populate_zip_boundaries => [:environment] do
puts "Right now we're only including zip codes that overlap with Lane County, OR."
Expand All @@ -9,7 +12,7 @@ task :populate_zip_boundaries => [:environment] do
add_count = 0

# read in the JSON line by line
IO.foreach("/suyc/db/data/us_zip_codes.json") { |line|
IO.foreach("/suyc/data/us_zip_codes.json") { |line|

# parse the line
data = JSON.parse(line)
Expand All @@ -23,35 +26,21 @@ task :populate_zip_boundaries => [:environment] do
# if it's already in ZipBoundary, ignore it
next if ZipBoundary.where(name: data["zip_code"]).present?

# clean up the lat long pairs
bounds = clean_bounds(data["zcta_geom"])
# get polygon
polygon = GeoRuby::SimpleFeatures::MultiPolygon.from_ewkt(data["zcta_geom"])

zip_type = "Polygon"
if data["zcta_geom"].start_with?('MULTIPOLYGON')
zip_type = "MultiPolygon"
end

# otherwise, create a new record
ZipBoundary.create(name: data["zip_code"], zip_type: zip_type, bounds: bounds)
ZipBoundary.create(name: data["zip_code"], zip_type: zip_type, bounds: polygon.to_coordinates())

# increment the count
add_count += 1
}

puts "Added #{add_count} zip codes."

end

def clean_bounds(b)
if b.start_with?('MULTIPOLYGON')
cords = b.gsub('MULTIPOLYGON(((', '').gsub(')))', '')
cords = [cords.split(',').collect{|c| c.split(" ").map(&:to_f).reverse()}]

return cords
else
cords = b.gsub('POLYGON((', '').gsub('))', '')
cords = [cords.split(',').collect{|c| c.split(" ").map(&:to_f).reverse()}]

return cords
end
end
end

0 comments on commit ad1ab62

Please sign in to comment.