Ruby. Working with PostGIS extension

Postgres is well known as a modern and powerful database. One of the possibilities is support for working with geospatial data. Initially, this requires the installation of the PostGIS extension. Next, in your rails application, you need to use gems such as:
  • gem 'activerecord-postgis-adapter'
  • gem 'rgeo'
  • gem 'geocoder'

Below is an example of working with a truck model, in which one of the fields (let's call it waypoints) has a special data type - geometry(linestring).


# app/lib/geo.rb
class Geo
  SRID = 4326
  
  METHODS = %i[point line_string]
  
  class << self
    delegate *METHODS, prefix: 'cartesian', to: :cartesian_factory
    delegate *METHODS, prefix: 'spherical', to: :spherical_factory

    def cartesian_factory
      @cartesian_factory ||= RGeo::Cartesian.factory
    end

    def spherical_factory
      @spherical_factory ||= RGeo::Geographic.spherical_factory(srid: SRID)
    end

    def pairs_to_points(pairs)
      pairs.map { |pair| point(pair[0], pair[1]) }
    end
    
    def pairs_to_line_string(pairs)
      points = pairs_to_points(pairs)
      cartesian_line_string(points)
    end
  end
end


# app/models/concerns/geo_workable.rb
module GeoWorkable
  extend ActiveSupport::Concern

  METHODS = %i[pairs_to_points pairs_to_line_string].freeze

  included do
    delegate *METHODS, to: Geo
  end

  class_methods do
    delegate *METHODS, to: Geo
  end
end


# app/models/track.rb
class Track < ActiveRecord::Base
  include GeoWorkable
  
  def coordinates
    self.waypoints.coordinates
  end
  
  def update_waypoints(coordinates)
    self.waypoints = pairs_to_line_string(coordinates)
    self.save
  end
end


track = Track.find(...)
coordinates = track.coordinates # [[longitude, latitude], [longitude, latitude], ...]
# do some transformations on that coordinates
track.update_waypoints(coordinates)

No comments :

Post a Comment