cartodb/app/models/named_map/presenter.rb
2020-06-15 10:58:47 +08:00

128 lines
5.0 KiB
Ruby

module CartoDB
module NamedMapsWrapper
class Presenter
NAMED_MAP_TYPE = 'namedmap'
LAYER_TYPES_TO_DECORATE = [ 'torque' ]
DEFAULT_TILER_FILTER = 'mapnik'
# @throws NamedMapsPresenterError
def initialize(visualization, layergroup, options, configuration)
@visualization = visualization
@options = options
@configuration = configuration
@layergroup_data = layergroup
@named_map_name = Carto::NamedMaps::Template.new(Carto::Visualization.find(@visualization.id)).name
end
# Prepares additional data to decorate layers in the LAYER_TYPES_TO_DECORATE list
# - Parameters set inside as nil will remove the field itself from the layer data
# @throws NamedMapsPresenterError
def get_decoration_for_layer(layer_type, layer_index)
return {} unless LAYER_TYPES_TO_DECORATE.include? layer_type
{
'named_map' => {
'name' => @named_map_name,
'layer_index' => layer_index,
'params' => placeholders_data
},
'query' => nil #do not expose SQL query on Torque layers with named maps
}
end
# Prepare a PORO (Hash object) for easy JSONification
# @see https://github.com/CartoDB/carto.js/blob/privacy-maps/doc/vizjson_format.md
# @throws NamedMapsPresenterError
def to_poro
if @visualization.layers(:cartodb).size == 0
# When there are no layers don't return named map data
nil
else
api_templates_type = @options.fetch(:https_request, false) ? 'private' : 'public'
privacy_type = @visualization.password_protected? ? 'private': api_templates_type
{
type: NAMED_MAP_TYPE,
order: 1,
options: {
type: NAMED_MAP_TYPE,
user_name: @options.fetch(:user_name),
maps_api_template: ApplicationHelper.maps_api_template(privacy_type),
sql_api_template: ApplicationHelper.sql_api_template(privacy_type),
# tiler_* and sql_api_* are kept for backwards compatibility
tiler_protocol: @visualization.password_protected? ?
@configuration[:tiler]['private']['protocol'] :
@configuration[:tiler]['public']['protocol'],
tiler_domain: @visualization.password_protected? ?
@configuration[:tiler]['private']['domain'] :
@configuration[:tiler]['public']['domain'],
tiler_port: @visualization.password_protected? ?
@configuration[:tiler]['private']['port'] :
@configuration[:tiler]['public']['port'],
filter: @configuration[:tiler].fetch('filter', DEFAULT_TILER_FILTER),
named_map: {
name: @named_map_name,
stat_tag: @visualization.id,
params: placeholders_data,
layers: configure_layers_data
},
attribution: @visualization.attributions_from_derived_visualizations.join(', ')
}
}
end
end
private
def placeholders_data
data = {}
@layergroup_data.each { |layer|
data["layer#{layer[:index].to_s}".to_sym] = layer[:visible] ? 1: 0
}
data
end
# Extract relevant information from layers
def configure_layers_data
# Http/base layers don't appear at viz.json
layers = @visualization.layers(:cartodb)
layers_data = Array.new
layers.each { |layer|
layer_vizjson = layer.get_presenter(@options, @configuration).to_vizjson_v2
layers_data.push(data_for_carto_layer(layer_vizjson))
}
layers_data
end
def data_for_carto_layer(layer_vizjson)
# TODO: this id will probably be removed from named maps
data = {
id: layer_vizjson[:id],
layer_name: layer_vizjson[:options][:layer_name],
interactivity: layer_vizjson[:options][:interactivity],
visible: layer_vizjson[:visible]
}
vizjson_infowindow = layer_vizjson[:infowindow]
vizjson_infowindow_fields = vizjson_infowindow['fields'] if vizjson_infowindow
if vizjson_infowindow.present? && vizjson_infowindow_fields && !vizjson_infowindow_fields.empty?
data[:infowindow] = vizjson_infowindow
end
vizjson_tooltip = layer_vizjson[:tooltip]
vizjson_tooltip_fields = vizjson_tooltip['fields'] if vizjson_tooltip
if vizjson_tooltip.present? && vizjson_tooltip_fields && !vizjson_tooltip_fields.empty?
data[:tooltip] = vizjson_tooltip
end
vizjson_legend = layer_vizjson[:legend]
data[:legend] = vizjson_legend if vizjson_legend.present? && vizjson_legend.fetch('type') != 'none'
data
end
end
end
end