Created
October 26, 2010 21:55
-
-
Save jpmckinney/647909 to your computer and use it in GitHub Desktop.
Transforms attendee data into a KML file that can be uploaded to, e.g., GeoCommons
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
require 'rubygems' | |
require 'date' | |
require 'pdf/reader' | |
require 'graticule' | |
require 'builder' | |
class String | |
def is_numeric? | |
Float self rescue false | |
end | |
end | |
class Object | |
def blank? | |
respond_to?(:empty?) ? empty? : !self | |
end | |
def present? | |
!blank? | |
end | |
end | |
class Place | |
attr_accessor :name, :total, :latitude, :longitude | |
def initialize | |
@name = '' | |
end | |
def coordinates=(array) | |
@latitude, @longitude = array | |
end | |
end | |
class Province < Place | |
# Nothing to see here. | |
end | |
class City < Place | |
attr_accessor :province | |
end | |
class Receiver | |
attr_accessor :places | |
def initialize | |
@places = [] | |
@reading = false # Change state to "reading data". | |
@stopping = false | |
end | |
def show_text(string, *params) | |
add_to_list(string) | |
end | |
def show_text_with_positioning(array, *params) | |
string = array.select{ |x| x.is_a? String }.join | |
case string | |
when 'Alberta' | |
@reading = true | |
@places << Province.new | |
when 'Aldergrove' | |
@reading = true | |
@places << City.new | |
when 'Yukon', 'Lethbridge' | |
@stopping = true | |
end | |
add_to_list(string) | |
end | |
def add_to_list(string) | |
if @reading and string.strip.present? | |
if string.is_numeric? | |
@places.last.total = string | |
if @stopping | |
@reading = @stopping = false | |
else | |
@places << places.last.class.new | |
end | |
elsif string[/^[A-Z]{2,3}$/] | |
case string # Fix incorrect province abbreviations. | |
when 'NF' | |
string = 'NL' | |
when 'NWT' | |
string = 'NT' | |
when 'PEI' | |
string = 'PE' | |
when 'YK' | |
string = 'YT' | |
end | |
@places.last.province = string | |
else | |
@places.last.name << string | |
end | |
end | |
end | |
end | |
abort "Usage: #{$0} province|city" unless %w(province city).include? ARGV[0] | |
receiver = Receiver.new | |
# source: http://www.waterlution.org/wp-content/uploads/2010/10/Waterlution_CWIL_PR_Oct25.pdf | |
pdf = PDF::Reader.file(File.expand_path('../Waterlution_CWIL_PR_Oct25.pdf', __FILE__), receiver) | |
geocoder = Graticule.service(:google).new 'ABQIAAAACjg5EelPDHaItWLh83iDnxT8EWQz3r5LEGmiOQEh6eS8' | |
provinces, cities = receiver.places.partition { |x| x.is_a? Province } | |
case ARGV[0] | |
when 'province' | |
scope = 'Province' | |
provinces.each do |province| | |
province.coordinates = geocoder.locate("#{province.name}, Canada").coordinates | |
end | |
places = provinces | |
when 'city' | |
scope = 'City' | |
cities.each do |city| | |
city.coordinates = geocoder.locate("#{city.name}, #{city.province}, Canada").coordinates | |
end | |
places = cities | |
end | |
xml = Builder::XmlMarkup.new(:target => $stdout, :indent => 2) | |
xml.instruct! | |
xml.kml(:xmlns => 'http://www.opengis.net/kml/2.2', :'xmlns:atom' => 'http://www.w3.org/2005/Atom') do | |
xml.Document do | |
xml.name "The Canadian Water Innovation Lab 2010: Attendee Map by #{scope}" | |
xml.tag!('atom:author') do | |
xml.tag!('atom:name', 'James McKinney') | |
end | |
xml.tag!('atom:link', :href => 'http://www.slashpoundbang.com/') | |
xml.TimeStamp do | |
xml.when DateTime.now.strftime | |
end | |
places.each do |place| | |
xml.Placemark do | |
xml.name place.name | |
xml.ExtendedData do | |
xml.Data(:name => 'attendees') do | |
xml.value place.total | |
end | |
xml.Point do | |
xml.coordinates("#{place.longitude},#{place.latitude}") | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment