Last active
June 11, 2017 22:19
-
-
Save joshuawscott/2319f19bdd0cd020bfc1 to your computer and use it in GitHub Desktop.
Polygons/Points/Arrays using Sequel for PostgreSQL
This file contains 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
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) |
This file contains 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
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