Class: ImageDownloader

Inherits:
Object
  • Object
show all
Defined in:
lib/gsv_downloader/image_downloader.rb

Overview

Google Street View Images Downloader

gsv_images = imageDonwloader.new
gsv_images.download("3ed539212sSA",2, "./images")

Direct Known Subclasses

ImageDownloaderParallel

Instance Method Summary collapse

Constructor Details

#initialize(tmp_path = "./tmp") ⇒ ImageDownloader

Returns a new instance of ImageDownloader.



12
13
14
15
16
17
18
19
20
21
# File 'lib/gsv_downloader/image_downloader.rb', line 12

def initialize(tmp_path = "./tmp")

	set_tmp_dir(tmp_path)

	@conn = Faraday.new(:url => "http://cbk1.google.com") do |faraday|
		faraday.request :retry, max: 3, interval: 2
		faraday.response :raise_error
		faraday.adapter  Faraday.default_adapter
	end
end

Instance Method Details

#combine_tiles(tiles, zoom, panoID) ⇒ Object



117
118
119
120
# File 'lib/gsv_downloader/image_downloader.rb', line 117

def combine_tiles(tiles, zoom, panoID)
	cmd = "montage #{tiles.join(" ")} -geometry +0+0 -tile #{get_nb_tiles(zoom,:x)}x#{get_nb_tiles(zoom,:y)} #{@tmp_path}/#{panoID}.jpg"
	Subexec.run cmd, :timeout => 0
end

#crop_pano(panoID, zoom_level, dest_filename) ⇒ Object



96
97
98
99
100
101
102
103
104
105
# File 'lib/gsv_downloader/image_downloader.rb', line 96

def crop_pano(panoID, zoom_level, dest_filename)
	crop = case zoom_level
		when 3 then "#{3584 - 256}x#{2048 - 384}"
		when 4 then "#{6656}x#{3584 - 256}" #-256
		when 5 then "#{13312}x#{6656}"
	end
	# WARNING: may not overwrite previous file
	cmd = "convert #{@tmp_path}/#{panoID}.jpg  -crop #{crop}+0+0  #{dest_filename} "
		 Subexec.run cmd, :timeout => 0
end

#download(panoID, zoom_level = 4, dest_dir = "./images") ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/gsv_downloader/image_downloader.rb', line 29

def download(panoID,  zoom_level = 4, dest_dir = "./images")

	FileUtils.mkdir_p(dest_dir) #create dir if not already present

	dest_filename = create_filename(panoID, zoom_level, dest_dir)

	if Pathname.new(dest_filename).exist?
		puts "images #{panoID} already existing in #{dest_dir}"
	else
		# puts "fetching #{panoID} to #{dest_dir}"
		# download each tile
		tiles_filenames = download_tiles(panoID, zoom_level)

		# combine tiles
		combine_tiles(tiles_filenames, zoom_level, panoID)

		# crop panorama
		crop_pano(panoID, zoom_level, dest_filename)

		# remove tmps
		FileUtils.rm_f("#{@tmp_path}/#{panoID}.jpg")
		tiles_filenames.each do |tile_filename|
	  	FileUtils.rm_f(tile_filename)
	  end
	end
  dest_filename
end

#download_tile(zoom, x, y, panoID) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/gsv_downloader/image_downloader.rb', line 66

def download_tile(zoom, x, y, panoID)
	url = "/cbk?output=tile&zoom=#{zoom}&x=#{x}&y=#{y}&v=4&panoid=#{panoID}"
	#resp = Net::HTTP.get_response(URI.parse(url))
	begin
		resp = @conn.get do |req|
			req.url url
		  req.options[:timeout] = 2           # open/read timeout in seconds
  		req.options[:open_timeout] = 2
  	end
 	rescue Exception => err
 		 raise Exception.new("error downloading tile #{panoID} #{x}x#{y} zoom:#{zoom}")
 	end

	filename = "#{@tmp_path}/tile-#{panoID}-#{x}-#{y}.jpg"
	open(filename, 'wb') do |file|
 		file.write(resp.body)
	end
	filename
end

#download_tiles(panoID, zoom_level) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/gsv_downloader/image_downloader.rb', line 57

def download_tiles(panoID, zoom_level)
	tiles_filenames = []
	get_tiles(zoom_level) do |x, y|
		tiles_filenames << download_tile(zoom_level, x, y, panoID)
		#puts "downloaded tile  x=#{x},y=#{y}"
	end
	tiles_filenames
end

#get_nb_tiles(zoom_level, axis) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/gsv_downloader/image_downloader.rb', line 107

def get_nb_tiles(zoom_level, axis)
	zoom_level -= 1 if axis == :y
	case zoom_level
		when 2 then 4
		when 3 then 7
		when 4 then 13
		when 5 then 26
	end
end

#get_tiles(zoom_level = 3) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/gsv_downloader/image_downloader.rb', line 86

def get_tiles( zoom_level = 3)
	last_x_tile = get_nb_tiles(zoom_level,:x) - 1
	last_y_tile = get_nb_tiles(zoom_level,:y) - 1
	(0..last_y_tile).each do |y|
		(0..last_x_tile).each do |x|
			yield(x,y)
		end
	end
end

#set_tmp_dir(tmp_path) ⇒ Object



23
24
25
26
# File 'lib/gsv_downloader/image_downloader.rb', line 23

def set_tmp_dir(tmp_path)
	@tmp_path = tmp_path
	FileUtils.mkdir_p(@tmp_path)
end