namespace :mapfile do require 'rubygems' require 'iconv' desc "Create a topic from a mapfile. MAPFILE=file SITE=host DBONLY=false" task :import_topic => :environment do mapfile = ENV['MAPFILE'] site = ENV['SITE'] || SITE_DEFAULT #Use empty string for unpublished map dbonly = ENV['DBONLY'] || false if mapfile.nil? puts "Error: Missing argument MAPFILE" else import = MapfileImport.new(mapfile, site) import.import(dbonly) end end desc "Create a topic from a mapfile. MAPFILE=file" task :gen_topic_legends => :environment do topicname = ENV['TOPIC'] topics = Topic.scoped topics = topics.where(:name => topicname) if topicname topics.each do |topic| MapfileImport.gen_topic_legend(topic) end end class MapfileImport begin require 'ruby_mapscript' include Mapscript rescue Exception => e #Ignore missing mapscript lib on Windows end include FileUtils def initialize(mapfile, site) @map = MapObj.new(mapfile) @site = site || DEFAULT_SITE end def import(dbonly = false) topic = Topic.find_or_create_by_name(@map.name) topic.title = @map.web.metadata['ows_title'] || @map.web.metadata['wms_title'] puts "Importing topic '#{topic.name}' with title '#{topic.title}'" topic.print_title = topic.title topic.geolion_gdd_intranet = @map.web.metadata['geolion_gdd_intranet'] topic.geolion_gdd_internet = @map.web.metadata['geolion_gdd_internet'] topic.minscale = @map.web.metadata['gb_minscale'] topic.main_layer = true if topic.main_layer.nil? topic.save! topic.topics_layers.destroy_all topic.categories_topics.destroy_all Layer.unused.destroy_all SublayerGroup.unused.destroy_all category = @map.web.metadata['gb_category'] || 'Uncategorized' topic.categories << Category.find_or_create_by_title(category) sublayer_groups = {} #Show Symbols #@map.symbolset.symbols.each do |symbol| # puts "Symbol #{symbol.name} #{symbol.imagepath}" #end @map.layers.each_with_index do |mlayer, layerno| topic_name = mlayer.metadata['gb_topic_name'] || topic.name queryable = mlayer.template != nil layer_name = if mlayer.group && !queryable mlayer.group else mlayer.name end layer = Layer.where(:name => layer_name, :topic_name => topic_name).first if mlayer.group && !queryable group_layer_created = !layer.nil? && topic.layers.include?(layer) if group_layer_created #Update scales only puts "Hiding grouped layer '#{mlayer.name}'" layer.minscale = [layer.minscale || mlayer.minscaledenom, mlayer.minscaledenom].min if mlayer.minscaledenom >= 0 layer.maxscale = [layer.maxscale || mlayer.maxscaledenom, mlayer.maxscaledenom].max if mlayer.maxscaledenom >= 0 layer.save! next end end layer ||= Layer.new layer.name = layer_name puts "Creating layer '#{layer.name}'" layer.title = mlayer.metadata['wms_title'] layer.geolion_gds = mlayer.metadata['geolion_gds'] layer.selection_style = mlayer.metadata['gb_selection_style'] layer.topic_name = topic_name layer.minscale = mlayer.minscaledenom if mlayer.minscaledenom >= 0 layer.maxscale = mlayer.maxscaledenom if mlayer.maxscaledenom >= 0 puts "Warning: maxcale of layer '#{layer.name}' undefined" unless layer.maxscale if mlayer.connectiontype == MS_POSTGIS mlayer.data =~ /FROM ["']?(\w+)["']?/i layer.table = $1 puts "Warning: Couldn't extract table name of layer '#{layer.name}' from data '#{mlayer.data}'" if layer.table.blank? mlayer.data =~ /UNIQUE (\w+)/i layer.pkey = $1 || 'oid' elsif mlayer.connectiontype == MS_WMS url = mlayer.getWMSFeatureInfoURL(@map, 0, 0, 10, "text/xml") #extract necessary params params = url.split(/[?&]/).select {|p| k,v=p.split('='); %w(LAYERS QUERY_LAYERS VERSION SRS CRS).include?(k) || k =~ /^https?:/ } layer.table = "#{params.shift}?#{params.join('&')}" end #ident_fields+alias_fields if mlayer.metadata.key?('wms_include_items') layer.ident_fields = mlayer.metadata['wms_include_items'].gsub(/,\s+/, ',') layer.alias_fields = layer.ident_fields.split(',').collect do |ident_field| mlayer.metadata["gml_#{ident_field}_alias"] || ident_field end.join(',') end #sublayer_group if mlayer.metadata.key?('wms_group_title') group_name = mlayer.metadata['wms_group_title'] layer.sublayer_group = sublayer_groups[group_name] if layer.sublayer_group.nil? layer.sublayer_group = SublayerGroup.create!(:name => group_name) sublayer_groups[group_name] = layer.sublayer_group end end #searchdistance layer.searchdistance = mlayer.metadata['gb_searchdistance'] || case mlayer.type when MS_LAYER_POINT then 50 when MS_LAYER_LINE then 50 when MS_LAYER_POLYGON then 0 else 50 #Annotation end layer.save! unless dbonly #Info & Legend mkdir_p File.dirname(layer.info_file_auto) if queryable if mlayer.type == MS_LAYER_RASTER || mlayer.type == MS_LAYER_ANNOTATION puts "Warning: Raster/Anntotation layer '#{layer.name}' is queryable (TEMPLATE #{mlayer.template})" end #puts "Creating #{layer.info_file_auto}" fields = layer.ident_fields.split(',') rescue [] aliases = if fields.empty? puts "Warning: Query layer '#{layer.name}' has no attribute definition (wms_include_items)" [] else layer.alias_fields.split(',') end infotab_template = "_infotable_auto" template = File.open(File.join(File.dirname(__FILE__), 'templates', "#{infotab_template}.html.erb")).read template = ERB.new(template, nil, '<>') File.open(layer.info_file_auto, 'w') do |file| file << template.result(binding) end end # Layer legend legend_icon_path = File.join(Rails.root, 'public', 'images', 'custom', topic_name.downcase) mkdir_p legend_icon_path if mlayer.type != MS_LAYER_RASTER && mlayer.type != MS_LAYER_ANNOTATION #puts "Creating #{layer.legend_file_auto}" File.open(layer.legend_file_auto, 'w') do |file| file << "
#{layer.title}
EOS file << " <%= metatag('#{layer.geolion_gds}') %>" if layer.geolion_gds file <<<