Skip to content

Commit

Permalink
dendro sites finally show up in the map
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinHinz committed Dec 16, 2024
1 parent 278d40f commit e3cde77
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 182 deletions.
214 changes: 122 additions & 92 deletions app/controllers/xronos_data_controller.rb
Original file line number Diff line number Diff line change
@@ -1,118 +1,148 @@
class XronosDataController < ApplicationController
include Pagy::Backend

before_action :set_data, only: [:index]

def turn_off_lasso
session[:spatial_lasso_selection] = nil
redirect_to request.env["HTTP_REFERER"]#:action => 'map'
reset_session_key(:spatial_lasso_selection)
end

def reset_manual_table_selection
session[:manual_table_selection] = nil
redirect_to request.env["HTTP_REFERER"]#:action => 'index'
reset_session_key(:manual_table_selection)
end

def index
@data = XronosData.new(filter_params, select_params)
@raw_filter_params = filter_params
logger.debug { "Parsed filters: #{@data.filters.inspect}" }
@sites = @data.xrons.select("sites.id", "sites.lng", "sites.lat", "sites.name").distinct


respond_to do |format|
format.html {
@pagy, @xrons = pagy(@data.xrons)
render layout: "full_page"
}
format.json { render json: @data }
format.geojson {
render json: Site.connection.exec_query(Site.select("json_agg(geojson) AS measurements").from("(select jsonb_build_object(
'type', 'Feature',
'geometry', jsonb_build_object(
'type', 'Point',
'coordinates', jsonb_build_array(lng, lat)
),
'properties', jsonb_build_object(
'name', name,
'id', id
)
) AS geojson from (" + @sites.to_sql+ ") AS subquery1) AS subquery2").to_sql)[0]['measurements'], adapter: nil, serializer: nil
}
format.csv {
query = "COPY (SELECT * FROM data_views WHERE id IN (" + @data.xrons.pluck(:id).join(', ').to_s + ") ) TO STDOUT WITH CSV HEADER"

connection = ActiveRecord::Base.connection.raw_connection
csv_data = ""

connection.copy_data(query) do
while row = connection.get_copy_data
csv_data << row
end
end

render plain: csv_data, content_type: 'text/csv', filename: "data_#{Date.today}.csv"
}
format.html { render_index_html }
format.json { render json: @data.xrons }
format.geojson { render_geojson }
format.csv { render_csv }
end
end

private

def set_data
# Initialize data for C14 and Dendro, applying filters and selections
@c14_data = XronosData.new(filter_params, select_params, :c14)
@dendro_data = XronosData.new(filter_params, select_params, :dendro)

# Assign the default data view to @data (e.g., C14 by default)
@data = @c14_data

# Fetch site data from both C14 and Dendro queries
c14_sites = @c14_data.xrons
.joins("LEFT JOIN sites ON sites.id = contexts.site_id")
.select("sites.id AS site_id, sites.lng, sites.lat, sites.name AS site_name")
.distinct

dendro_sites = @dendro_data.xrons
.joins("LEFT JOIN sites ON sites.id = contexts.site_id")
.select("sites.id AS site_id, sites.lng, sites.lat, sites.name AS site_name")
.distinct

# Combine site queries and remove duplicates
combined_sites_query = "(#{c14_sites.to_sql} UNION #{dendro_sites.to_sql}) AS combined_sites"
@sites = Site.from(combined_sites_query).select("site_id, lng, lat, site_name").distinct
end

def reset_session_key(key)
session[key] = nil
redirect_back(fallback_location: root_path)
end

def filter_params
# DEFINE PERMITTED FILTERS
# `:name` -> only one value allowed
# `name: []` -> only array of values allowed
params.fetch(:filter, {}).permit(
{c14s: [
:lab_identifier,
{lab_identifier: []},
{bp: []}
]},
{cals: [
:tpq,
{tpq: []},
:taq,
{taq: []}
]},
{c14_labs: [
:name,
{name: []}
]},
{contexts: [
:name,
{name: []}
]},
{materials: [
:name,
{name: []}
]},
{taxons: [
:name,
{name: []}
]},
{typos: [
:name,
{name: []}
]},
{references: [
:short_ref,
{short_ref: []},
]},
{sites: [
:name,
{name: []},
:country_code,
{country_code: []},
{lat: []},
{lng: []}
]},
{site_types: [
:name,
{name: []}
]}
c14s: [
:lab_identifier, { lab_identifier: [] }, { bp: [] }
],
cals: [
:tpq, { tpq: [] }, :taq, { taq: [] }
],
c14_labs: [
:name, { name: [] }
],
contexts: [
:name, { name: [] }
],
materials: [
:name, { name: [] }
],
taxons: [
:name, { name: [] }
],
typos: [
:name, { name: [] }
],
references: [
:short_ref, { short_ref: [] }
],
sites: [
:name, { name: [] }, :country_code, { country_code: [] },
{ lat: [] }, { lng: [] }
],
site_types: [
:name, { name: [] }
]
)
end

# TODO: is this safe???
def select_params
params.fetch(:select, {})
end

end
def render_index_html
@pagy, @xrons = pagy(@data.xrons)
render layout: "full_page"
end

def render_geojson
geojson_query = Site.select("json_agg(geojson) AS measurements")
.from(build_geojson_subquery)
render json: Site.connection.exec_query(geojson_query.to_sql)[0]['measurements'],
adapter: nil, serializer: nil
end

def build_geojson_subquery
<<~SQL
(SELECT jsonb_build_object(
'type', 'Feature',
'geometry', jsonb_build_object(
'type', 'Point',
'coordinates', jsonb_build_array(lng, lat)
),
'properties', jsonb_build_object(
'name', site_name,
'id', site_id
)
) AS geojson FROM (#{@sites.to_sql}) AS subquery1) AS subquery2
SQL
end

def render_csv
query = <<~SQL
COPY (
SELECT * FROM data_views WHERE id IN (#{@data.xrons.pluck(:id).join(', ')})
) TO STDOUT WITH CSV HEADER
SQL

csv_data = fetch_csv_data(query)
render plain: csv_data, content_type: 'text/csv', filename: "data_#{Date.today}.csv"
end

def fetch_csv_data(query)
connection = ActiveRecord::Base.connection.raw_connection
csv_data = ""

connection.copy_data(query) do
while (row = connection.get_copy_data)
csv_data << row
end
end

csv_data
end
end
1 change: 1 addition & 0 deletions app/models/c14.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#
class C14 < ApplicationRecord

has_one :chron, as: :recordable
belongs_to :sample
accepts_nested_attributes_for :sample, reject_if: :all_blank

Expand Down
32 changes: 32 additions & 0 deletions app/models/chron.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Chron < ApplicationRecord
self.abstract_class = true

def self.fetch_c14
C14
.left_outer_joins(:c14_lab)
.joins("LEFT OUTER JOIN cals on (cals.c14_age = c14s.bp AND cals.c14_error = c14s.std)")
.left_outer_joins(sample: [
:material,
:taxon,
context: [
site: [
:site_types
]
]
])
.all.distinct
end
def self.fetch_dendro
Dendro
.left_outer_joins(sample: [
:material,
:taxon,
context: [
site: [
:site_types
]
]
])
.all.distinct
end
end
2 changes: 2 additions & 0 deletions app/models/dendro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
# fk_rails_... (sample_id => samples.id)
#
class Dendro < ApplicationRecord

has_one :chron, as: :recordable
belongs_to :sample
accepts_nested_attributes_for :sample, reject_if: :all_blank

Expand Down
Loading

0 comments on commit e3cde77

Please sign in to comment.