Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #MODULE IS AT THE BOTTOM
- class ShapeFile
- include GeoRuby::Shp4r
- include PortableFiles
- attr_accessor :files, :columns
- attr_reader :shape_file, :table_name
- def initialize(options ={})
- @files = {}
- @files[:shp_file] = options[:shp_file]
- @files[:shx_file] = options[:shx_file]
- @files[:dbf_file]= options[:dbf_file]
- end
- def read_columns
- @columns = Array.new
- each_column do |field|
- @columns << { :name => field.name.downcase, :type => field_type_to_rails(field.type) }
- end
- end
- def import_data(fields = [])
- cl = classify
- ShpFile.open(self) do |shp|
- shp.each do |shape|
- record = cl.new
- shp.fields.each do |field|
- record[field.name.downcase] = shape.data[field.name] if fields.include? field.name.downcase or fields.blank?
- end
- record.the_geom = shape.geometry
- record.save
- end
- end
- end
- def each_column
- ShpFile.open(self) do |shp|
- shp.fields.each do |field|
- yield(field)
- end
- end
- end
- private
- def field_type_to_rails(type)
- case type
- when 'N' then :integer
- when 'F' then :float
- when 'D' then :date
- else
- :string
- end
- end
- end
- module PortableFiles
- attr_accessor :file_paths
- #adds table prefix 'layer_' to each layer
- def table_name=(name)
- @table_name = "layer_table_#{name}"
- end
- # adds the layer to the layers table
- def add_layer
- Layer.create(:name => @table_name, :table_name => @table_name.to_s, :geometric_column_name => "the_geom")
- end
- def table_has_unique_name?
- ActiveRecord::Base.connection.execute("SELECT * FROM information_schema.tables WHERE \"table_name\" = '#{@table_name}';").to_a.size == 0
- end
- def generate_table_name
- until table_has_unique_name? and @table_name
- self.table_name = ((rand*10000000000000).to_i).to_s
- end
- end
- def create_table
- #empty block : the columns will be added afterwards
- unless @table_name.blank?
- ActiveRecord::Schema.create_table(@table_name){}
- @table_created = true
- end
- end
- def create_table_structure
- if @table_created
- @columns.each do |column|
- begin
- ActiveRecord::Schema.add_column(@table_name, column[:name], column[:type])
- rescue
- puts "Couldnt add field #{column[:name].downcase}"
- end
- end
- ActiveRecord::Schema.add_column(table_name,"the_geom", :geometry,:null => false)
- ActiveRecord::Schema.add_index(table_name,"the_geom",:spatial => true)
- end
- end
- def classify
- temp_table_name = self.table_name
- Class.new(ActiveRecord::Base) do
- set_table_name temp_table_name
- end
- end
- # takes the contents of the files hash and copies them from temp files
- # and stores them in /temp_uploads. On upload, filename should get a random seed prefixed
- # to the filename, but i've added an extra 4 digit random seed to each filename just for
- # extra protextion. returns a hash with paths pointing to files as values. this is a workaround
- # because you cant store files in the session variable.
- def copy_files
- require 'ftools'
- @files.inject({}) do |result, file|
- seed = (rand * 1000).to_i
- File.syscopy(file[1].path, "temp_uploads/#{seed}" + file[1].path.split('/').last)
- result[file[0].to_sym] = "#{seed}#{file[1].path}"
- result
- end
- end
- def clear_files
- @files = nil
- end
- def prepare_for_session
- @file_paths = copy_files
- clear_files
- end
- def load_from_session
- @files = {}
- @file_paths.each do |file|
- @files[file[0]] = File.new("temp_uploads/#{file[1]}")
- end
- end
- end
Add Comment
Please, Sign In to add comment