Initial commit
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
module CartoDB
|
||||
module Map
|
||||
class Copier
|
||||
def copy(map, layers=true)
|
||||
new_map = new_map_from(map).save
|
||||
if layers
|
||||
copy_layers(map, new_map)
|
||||
end
|
||||
|
||||
new_map
|
||||
end
|
||||
|
||||
def new_map_from(map)
|
||||
@new_map ||= map.dup
|
||||
# Explicit association assignment to make user itself available, beyond its id, for validations
|
||||
if map.user
|
||||
@new_map.user ||= map.user
|
||||
end
|
||||
|
||||
# Default is to copy all attributes from the canonical map. This overrides it
|
||||
@new_map.scrollwheel = true
|
||||
@new_map.options[:scrollwheel] = true if @new_map.options
|
||||
|
||||
@new_map
|
||||
end
|
||||
|
||||
def copy_layers(origin_map, destination_map)
|
||||
layer_copies_from(origin_map).map do |layer|
|
||||
link(destination_map, layer)
|
||||
end
|
||||
end
|
||||
|
||||
def copy_base_layer(origin_map, destination_map)
|
||||
origin_map.user_layers.map do |layer|
|
||||
link(destination_map, layer.dup)
|
||||
end
|
||||
end
|
||||
|
||||
# TL;DR: adds data layers between existing base layers.
|
||||
#
|
||||
# Stacks data layer on top of the last data layer and/or
|
||||
# the first base layer found, and keeps any existing "top"
|
||||
# base layers on top.
|
||||
def copy_data_layers(origin_map, destination_map, user)
|
||||
last_data = destination_map.layers.reverse.find(&:data_layer?)
|
||||
order = if last_data
|
||||
last_data.order + 1
|
||||
else
|
||||
first_base = destination_map.layers.find(&:base_layer?)
|
||||
first_base ? (first_base.order + 1) : 0
|
||||
end
|
||||
|
||||
modified_layers = []
|
||||
|
||||
data_layer_copies_from(origin_map, user).map do |layer|
|
||||
# Push layers on top if needed
|
||||
if(destination_map.layers.map(&:order).include?(order))
|
||||
destination_map.layers.select { |l| l.order >= order }.each do |layer|
|
||||
layer.order += 1
|
||||
# layer must be saved later
|
||||
modified_layers << layer
|
||||
end
|
||||
end
|
||||
|
||||
layer.order = order
|
||||
link(destination_map, layer)
|
||||
# link saves
|
||||
modified_layers -= [layer]
|
||||
order += 1
|
||||
end
|
||||
|
||||
# this avoid extra saving (including validation) overhead
|
||||
modified_layers.uniq.map(&:save)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :map
|
||||
|
||||
def data_layer_copies_from(map, user)
|
||||
map.data_layers.map do |layer|
|
||||
new_layer = layer.dup
|
||||
new_layer.qualify_for_organization(map.user.username) if user.id != map.user.id
|
||||
|
||||
user.builder_enabled? ? reset_layer_styles(layer, new_layer) : new_layer
|
||||
end
|
||||
end
|
||||
|
||||
def layer_copies_from(map)
|
||||
map.layers.map(&:dup)
|
||||
end
|
||||
|
||||
def link(map, layer)
|
||||
layer.save
|
||||
layer.add_map(map)
|
||||
layer.save
|
||||
end
|
||||
|
||||
def reset_layer_styles(old_layer, new_layer)
|
||||
user_table = old_layer.user_tables.first
|
||||
return new_layer unless user_table
|
||||
|
||||
geometry_type = user_table.service.geometry_types.first
|
||||
return new_layer unless geometry_type
|
||||
|
||||
tile_style = ModelFactories::LayerFactory.builder_tile_style(geometry_type)
|
||||
new_layer.options['tile_style'] = tile_style
|
||||
|
||||
style_properties = ModelFactories::LayerFactory.style_properties(geometry_type)
|
||||
new_layer.options['style_properties'] = style_properties
|
||||
|
||||
new_layer
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
require 'json'
|
||||
require_relative '../../models/layer/presenter'
|
||||
|
||||
module CartoDB
|
||||
module Map
|
||||
class Presenter
|
||||
def initialize(map, options={}, configuration={}, logger=nil)
|
||||
@map = map
|
||||
@table = map.tables.first
|
||||
@options = { full: true }.merge(options)
|
||||
@configuration = configuration
|
||||
logger.info(map.inspect) if logger
|
||||
end
|
||||
|
||||
def to_poro
|
||||
|
||||
{
|
||||
version: "0.1.0",
|
||||
title: table.name,
|
||||
description: table.table_visualization.description,
|
||||
url: options.delete(:url),
|
||||
map_provider: map.provider,
|
||||
scrollwheel: map.scrollwheel,
|
||||
legends: map.legends,
|
||||
bounds: bounds_from(map),
|
||||
center: map.center,
|
||||
zoom: map.zoom,
|
||||
updated_at: map.viz_updated_at,
|
||||
|
||||
layers: [
|
||||
CartoDB::LayerModule::Presenter.new(map.base_layers.first, options, configuration).to_vizjson_v1,
|
||||
CartoDB::LayerModule::Presenter.new(map.data_layers.first, options, configuration).to_vizjson_v1
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :map, :table, :options, :configuration, :scrollwheel, :legends
|
||||
|
||||
def bounds_from(map)
|
||||
::JSON.parse("[#{map.view_bounds_sw}, #{map.view_bounds_ne}]")
|
||||
rescue => exception
|
||||
CartoDB::notify_exception(exception, user: current_user)
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user