Acessando dados espaciais pós -gis de trilhos
-
20-09-2019 - |
Pergunta
Preciso usar um banco de dados PostGIS existente no meu aplicativo Rails. Até agora, sou capaz de acessar o banco de dados bem, Georuby converte muito bem a coluna 'geom' em um objeto de ponto.
O que estou procurando é uma maneira fácil de executar consultas do tipo ActiveRecord nessas tabelas, por exemplo
Poi.find_within_radius(...)
ou consultas espaciais semelhantes, como cálculos de distância et. al.
Eu tentei várias combinações de Geokit, acompanhando plugins de trilhos, mas tenho certeza de que deve haver algo melhor no universo Ruby/Rails. Alguma dica?
Solução
Desde que você tem Georuby, coloque seu modelo POI
SRID = 4326 #WGS84
# geometry column is geom
# pt is a GeoRuby Point
def self.find_within_radius(pt, dist = 0.01)
self.all :conditions => "ST_DWithin(geom, ST_GeomFromText('POINT(#{pt.x} #{pt.y})', #{SRID}), #{dist})"
end
Para cálculos de distância, você pode usar métodos nos objetos de ponto
dist_circle = poi1.geom.spherical_distance(poi2.geom)
dist_projected = poi1.geom.euclidean_distance(poi2.geom)
Outras dicas
Adicionando a Resposta de Synecdoche, nos trilhos 3 você pode usar ActiveRelation
Escopos, o que permitiria encadear consultas.
Não testado:
# Poi.rb
scope :within, proc { |point, distance|
p = "POINT(#{point.x} #{point.y})"
where("ST_DWithin(geom, ST_GeomFromText('#{p}', #{SRID}), #{distance})")
}
scope :rated, proc { |rating| where(rating: rating) }
Uso:
home = Point.new(5,5)
Poi.rated(5).within(home, 25)
Mesmo se você não encorrer os escopos, na maioria das vezes é melhor do que usar métodos de classe.
ST_Distance () não significa que você provavelmente não possui o PostGIS instalado ou não criou um modelo PostGIS ... ou não criou seu banco de dados usando o modelo PostGIS se o modelo existir.