Skip to content

Instantly share code, notes, and snippets.

@restjohn
Last active February 23, 2016 20:32
Show Gist options
  • Save restjohn/5da343c1d202c5785181 to your computer and use it in GitHub Desktop.
Save restjohn/5da343c1d202c5785181 to your computer and use it in GitHub Desktop.
Simple Ruby CSV-to-GeoJSON command line utility
#!/bin/ruby
require 'smarter_csv'
require 'json'
require 'optparse'
class Csv2GeoJson
attr_reader :csv_source
attr_reader :lat_header
attr_reader :lon_header
attr_reader :geojson
def initialize(source)
@csv_source = source
@lat_header = nil
@lon_header = nil
@has_headers = true
@features = []
end
def map_lat_from(field_name)
@lat_header = field_name
self
end
def map_lon_from(field_name)
@lon_header = field_name
self
end
def has_headers(has_headers)
@has_headers = has_headers
self
end
def run
SmarterCSV.process(@csv_source, :headers_in_file => @has_headers).each do |row|
lat = row[@lat_header]
lon = row[@lon_header]
properties = {}
row.each do |header, field|
properties[header] = field unless header == @lat_header || header == @lon_header
end
@features.push({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [lon.to_f, lat.to_f]
},
properties: properties
})
end
@geojson = {
type: 'FeatureCollection',
crs: {
type: 'name',
properties: {
name: 'urn:ogc:def:crs:OGC:1.3:CRS84'
}
},
features: @features
}
end
end
options = {
lat: nil,
lon: nil,
no_headers: false
}
OptionParser.new do |opts|
opts.banner = 'csv2geojson usage:'
opts.on('--lat FIELD', 'the name of the header or column index containing the latitude values') \
do |field|
options[:lat] = field
end
opts.on('--lon FIELD', 'the name of the header or column index containing the longitude values') \
do |field|
options[:lon] = field
end
opts.on('--no-headers', 'indicate there is no header row') \
do
options[:no_headers] = true
end
end.parse!(ARGV)
geojson_hash = Csv2GeoJson.new(ARGF)
.map_lat_from(options[:lat])
.map_lon_from(options[:lon])
.has_headers(!options[:no_headers])
.run
puts JSON.pretty_generate(geojson_hash)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment