Skip to content

Instantly share code, notes, and snippets.

@joshuawscott
Last active June 11, 2017 22:19
Show Gist options
  • Save joshuawscott/2319f19bdd0cd020bfc1 to your computer and use it in GitHub Desktop.
Save joshuawscott/2319f19bdd0cd020bfc1 to your computer and use it in GitHub Desktop.
Polygons/Points/Arrays using Sequel for PostgreSQL
require 'sequel'
class Point
attr_accessor :long, :lat
def initialize(long, lat)
@long = long
@lat = lat
end
def self.from_str(str)
mstr = str.gsub /[()]/, ''
long, lat = mstr.split(',').map(&:to_f)
new long, lat
end
def to_s
"(#{long},#{lat})"
end
def inspect
"#<#{self.class.name}:#{to_s}>"
end
def sql_literal(*)
"'#{to_s}'"
end
end
class Polygon
attr_accessor :points
def initialize *points
@points = points
end
def self.from_str(string)
pairs = string.scan(/\(([0-9\-\.]+?),([0-9\-\.].+?)\)/).map {|s| s.map(&:to_f)}
points = pairs.map {|pair| Point.new *pair}
new *points
end
def sql_literal(*)
lit = "'("
lit << points.map(&:to_s).join(',')
lit << ")'"
end
end
# FIXME: set to your connection parameters
DB = Sequel.connect('postgres://jscott@localhost/test')
# Convert any pg point to Point class like Point.from_str(pg_string_value)
DB.conversion_procs[600] = Point.method(:from_str)
# Convert any pg polygon to Polygon class (with array of points)
DB.conversion_procs[604] = Polygon.method(:from_str)
# add the array handler
DB.extension :pg_array
# Because point[] is a non-standard type, we have to explicitly add it.
DB.register_array_type 'point'
geos = DB[:geos]
geo = geos.where(id: 1)
record = geo.first
def puts_detail(rec)
rec.keys.each do |field|
item = rec[field]
puts "#{field}: \n\tClass: #{item.class} \n\tinspect: #{item.inspect} \n\tto_s: #{item} \n\n"
end
end
puts_detail(record)
geos.filter(id: 2).delete
geos.insert(id: 2, center: Point.new(-97.7, 35.1), myshape: record[:myshape])
rec2 = geos.where(id: 2).first
puts "record 2"
puts_detail(rec2)
CREATE TABLE geos (
id integer,
myshape polygon,
center point,
point_arr point[],
myarr integer[]
);
INSERT INTO geos
VALUES(1, -- id integer
'((-113,47),(-85,47),(-113,35),(-85,35))', -- myshape polygon
'(-100,40)', -- center point
'{"(-113,47)","(-85,47)","(-113,35)","(-85,35)"}', -- point_arr point[]
'{1,2,3,4}' -- myarr integer[]
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment