PostGIS: Save a point with z coordinate to an existing ActiveRecord model
By Ryan Romanchuk
On
On
Prerequisite and Assumptions
# db/migration/add_location_column_to_pireps.rb
class AddLocationColumnToPireps < ActiveRecord::Migration[7.0]
def change
add_column :wx_pireps, :location, :st_point, geographic: true, has_z: true
add_index : wx_pireps, :location, using: :gist
end
end
# app/models/wx/pirep.rb
module Wx
class Pirep < ApplicationRecord
end
end
# config/initializers/rgeo_factories.rb
RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |store|
store.default = RGeo::Cartesian.preferred_factory
store.register(RGeo::Geographic.spherical_factory(srid: 4326, has_z_coordinate: true),
{ geo_type: 'point', srid: 4326, sql_type: 'geography' })
end
Usage
# Factory
pirep = Wx::Pirep.new
factory = pirep.location.factory
pirep.location = factory.point(-120.0, 43.0, 4500.0)
pirep.save!
# String literal via 'POINT( LON LAT Z)'
Wx::Pirep.create!(location: 'POINT(-129.0 43.0 4500.0)')
# Global
RGeo::Geographic.spherical_factory(srid: 4326, has_z_coordinate: true).point(longitude, latitude,
altitude_ft_msl).to_s
# => 'POINT(-129.0 43.0 4500.0)'
pirep.location.z
# => 4500.0