Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Transforms attendee data into a KML file that can be uploaded to, e.g., GeoCommons
# 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