class Onebox::Engine::GoogleMapsOnebox
Public Class Methods
===(other)
click to toggle source
Calls superclass method
# File lib/onebox/engine/google_maps_onebox.rb, line 9 def ===(other) if other.kind_of? URI @@matchers && @@matchers.any? { |m| other.to_s =~ m[:regexp] } else super end end
new(url, timeout = nil)
click to toggle source
Calls superclass method
Onebox::Engine::new
# File lib/onebox/engine/google_maps_onebox.rb, line 42 def initialize(url, timeout = nil) super resolve_url! rescue Net::HTTPServerException, Timeout::Error, Net::HTTPError, Errno::ECONNREFUSED, RuntimeError => err raise ArgumentError, "malformed url or unresolveable: #{err.message}" end
Private Class Methods
matches_regexp(key, regexp)
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 19 def matches_regexp(key, regexp) (@@matchers ||= []) << { key: key, regexp: regexp } end
Public Instance Methods
placeholder_html()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 57 def placeholder_html ::Onebox::Helpers.map_placeholder_html end
streetview?()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 49 def streetview? !!@streetview end
to_html()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 53 def to_html "<div class='maps-onebox'><iframe src=\"#{link}\" width=\"690\" height=\"400\" frameborder=\"0\" style=\"border:0\">#{placeholder_html}</iframe></div>" end
Private Instance Methods
data()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 63 def data { link: url, title: url } end
follow_redirect!()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 163 def follow_redirect! begin http = Net::HTTP.start( uri.host, uri.port, use_ssl: uri.scheme == 'https', open_timeout: timeout, read_timeout: timeout ) response = http.head(uri.path) raise "unexpected response code #{response.code}" unless %w(200 301 302).include?(response.code) @url = response.code == "200" ? uri.to_s : response["Location"] @uri = URI(@url) ensure http.finish rescue nil end end
match_url()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 148 def match_url @@matchers.each do |matcher| if m = matcher[:regexp].match(@url) return matcher[:key], m end end raise ArgumentError, "\"#{@url}\" does not match any known pattern" end
resolve_url!()
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 67 def resolve_url! @streetview = false type, match = match_url # Resolve shortened URL, if necessary if type == :short follow_redirect! type, match = match_url end # Try to get the old-maps URI, it is far easier to embed. if type == :standard retry_count = 10 while (retry_count -= 1) > 0 follow_redirect! type, match = match_url break if type != :standard sleep 0.1 end end case type when :standard # Fallback for map URLs that don't resolve into an easily embeddable old-style URI # Roadmaps use a "z" zoomlevel, satellite maps use "m" the horizontal width in meters # TODO: tilted satellite maps using "a,y,t" match = @url.match(/@(?<lon>[\d.-]+),(?<lat>[\d.-]+),(?<zoom>\d+)(?<mz>[mz])/) raise "unexpected standard url #{@url}" unless match zoom = match[:mz] == "z" ? match[:zoom] : Math.log2(57280048.0 / match[:zoom].to_f).round location = "#{match[:lon]},#{match[:lat]}" url = "https://maps.google.com/maps?ll=#{location}&z=#{zoom}&output=embed&dg=ntvb" url += "&q=#{$1}" if match = @url.match(/\/place\/([^\/\?]+)/) url += "&cid=#{($1 + $2).to_i(16)}" if @url.match(/!3m1!1s0x(\h{16}):0x(\h{16})/) @url = url @placeholder = "https://maps.googleapis.com/maps/api/staticmap?maptype=roadmap¢er=#{location}&zoom=#{zoom}&size=690x400&sensor=false" when :custom url = @url.dup @url = rewrite_custom_url(url, "embed") @placeholder = rewrite_custom_url(url, "thumbnail") @placeholder_height = @placeholder_width = 120 when :streetview @streetview = true panoid = match[:pano] lon = match[:lon].to_f.to_s lat = match[:lat].to_f.to_s heading = match[:heading].to_f.round(4).to_s pitch = (match[:pitch].to_f / 10.0).round(4).to_s fov = (match[:zoom].to_f / 100.0).round(4).to_s zoom = match[:zoom].to_f.round @url = "https://www.google.com/maps/embed?pb=!3m2!2sen!4v0!6m8!1m7!1s#{panoid}!2m2!1d#{lon}!2d#{lat}!3f#{heading}!4f#{pitch}!5f#{fov}" @placeholder = "https://maps.googleapis.com/maps/api/streetview?size=690x400&location=#{lon},#{lat}&pano=#{panoid}&fov=#{zoom}&heading=#{heading}&pitch=#{pitch}&sensor=false" when :canonical query = URI::decode_www_form(uri.query).to_h if !query.has_key?("ll") raise ArgumentError, "canonical url lacks location argument" unless query.has_key?("sll") query["ll"] = query["sll"] @url += "&ll=#{query["sll"]}" end location = query["ll"] if !query.has_key?("z") raise ArgumentError, "canonical url has incomplete query arguments" unless query.has_key?("spn") || query.has_key?("sspn") if !query.has_key?("spn") query["spn"] = query["sspn"] @url += "&spn=#{query["sspn"]}" end angle = query["spn"].split(",").first.to_f zoom = (Math.log(690.0 * 360.0 / angle / 256.0) / Math.log(2)).round else zoom = query["z"] end @url = @url.sub('output=classic', 'output=embed') @placeholder = "https://maps.googleapis.com/maps/api/staticmap?maptype=roadmap&size=690x400&sensor=false¢er=#{location}&zoom=#{zoom}" else raise "unexpected url type #{type.inspect}" end end
rewrite_custom_url(url, target)
click to toggle source
# File lib/onebox/engine/google_maps_onebox.rb, line 157 def rewrite_custom_url(url, target) uri = URI(url) uri.path = uri.path.sub(/(?<=^\/maps\/d\/)\w+$/, target) uri.to_s end