Skip to content

Instantly share code, notes, and snippets.

@agmcleod
Created April 12, 2011 15:39
Show Gist options
  • Save agmcleod/915743 to your computer and use it in GitHub Desktop.
Save agmcleod/915743 to your computer and use it in GitHub Desktop.
Parse csv data to KML format.
# copy and paste the code and save as a ruby file (.rb extension). Works with ruby 1.8.7 (default version on Snow Leopard).
# With the CSV file containing the data, run the script with the following syntax:
# ruby to_kml.rb <clientname> <filename>
# So if this was for DAC Group, and the file was locations.csv:
# ruby to_kml.rb DAC_Group locations.csv
#
# CSV Formatting requirements:
#
# Must contain columns: name, address, lat, lng. You may leave other columns in there if you wish. There is no downfall to doing so.
# To get lat/lng values, use the address or zipcode data that you have, and paste it into the form here: out2launchdigital.com/pagetorrent/geocoder/
# Once the page linked is done, it will respond with an alert message. It will take time, as it runs a request to google's api every few seconds.
require 'csv'
DOCTYPE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">"
client = ARGV[0] || 'Services'
input = ARGV[1]
unless File.exists?(input)
raise 'File not found'
end
def file_is_valid(row)
row = row.collect{ |c| c.downcase }
row.include?('name') && row.include?('address') && row.include?('lat') && row.include?('lng')
end
def humanize(str)
str.gsub(/\-/, ' ')
end
class Location
attr_accessor :name, :address, :lat, :lng, :client
def initialize(options = {})
if options.size > 0
@name = options[:name]
@address = options[:address]
@lat = options[:lat]
@lng = options[:lng]
@client = options[:client]
end
end
def to_kml
name = "#{@client} in #{@name}"
out = " <Placemark>\n"+
" <name>#{name}</name>\n"+
" <description>#{@address}</description>\n"+
" <Point>\n"+
" <coordinates>#{@lng},#{@lat}</coordinates>\n"+
" </Point>\n"+
" </Placemark>\n"
out.gsub(/\&/, '&amp;')
end
end
locations = []
first = true
name, address, lat, lng = nil,nil,nil,nil
CSV.foreach(input) do |row|
if first
first = false
if !file_is_valid(row)
raise "File is missing a required header. Must have columns of: name, address, lat, lng"
else
row.each_with_index do |col_name, i|
case col_name.downcase
when 'name'
name = i
when 'address'
address = i
when 'lat'
lat = i
when 'lng'
lng = i
end
end
end
else
locations << Location.new(:name => row[name], :address => row[address], :lat => row[lat], :lng => row[lng], :client => client)
end
end
File.open("kml_data.kml", 'w+') do |f|
f.write(DOCTYPE + "\n" + "<Document>\n"+ " <name>Terminix</name>\n")
locations.each do |location|
f.write("#{location.to_kml}\n")
end
f.write("</Document>\n</kml>")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment