从原始位置请求Google Street View全景图块

时间:2018-08-11 13:53:49

标签: google-maps google-street-view

我正在尝试请求Google街景图像,以便可以将整个全景图渲染为3D球形。

不幸的是,this API仅允许请求最高120°FoV。理想情况下,我需要可以投影到该球体上的等矩形图像。

然后我检查了请求全景图像以获取洞察力时Google Maps发出的请求,发现它发出的请求与此类似:

https://geo0.ggpht.com/cbk?cb_client=maps_sv.tactile&panoid=${panorama_id}&output=tile&x=${tile_x}&y=${tile_y}&zoom=${zoom_level}&nbt&fover=2 其中每个缩放级别将图像分成更多的图块,从而提供更高的分辨率。 (从视觉上解释here

这对我所做的事情来说是完美的-但是我发现它并没有返回我通过Metadata API获得的每个全景ID的响应。

仔细研究一下,我发现Google Maps有时会使用不同的参数向不同的端点发出请求,有些甚至会以完全不同的文件格式返回图像。

我现在对如何从这里解决这个问题一无所知。我无法嵌入街景Javascript API,因为I need to render this in an already 3D world,并且由于无法从中获取完整的全景图像,因此无法使用静态全景图API。

感谢任何想法,谢谢。 :)

1 个答案:

答案 0 :(得分:0)

您可以下载每张图像并将其保存在多维图像阵列中。然后,您可以将每个单独的图块绘制到空白位图上。 This article解释了如何下载所有磁贴。

这是我的c#代码,带有全景图ID,并返回等角的13312x6656位图,可以将其保存为任何图像格式:

public static Bitmap Panorama(string panoID)
    {
        ServicePointManager.DefaultConnectionLimit = Environment.ProcessorCount * 12;
        Image[,] images = new Image[26, 13];
        Parallel.For(0, 26, x =>
        {
            Parallel.For(0, 13, y =>
            {
                using (WebClient client = new WebClient())
                    images[x, y] = Image.FromStream(new MemoryStream(client.DownloadData(Get.TileURL(panoID, x, y)))); //converts downloaded byte array to image
            });
        });

        Bitmap result = new Bitmap(26 * 512, 13 * 512);
        for (int x = 0; x < 26; x++)
             for (int y = 0; y < 13; y++)
                 using (Graphics g = Graphics.FromImage(result))
                     g.DrawImage(images[x, y], x * 512, y * 512);
        return result;
    }

要获取网址,您还可以使用cbk0.google.com。 Get.TileURL:

public static string TileURL(string panoID, int x, int y, int zoomLevel = 5)
    {
        return "http://cbk0.google.com/cbk?output=tile&panoid=" + panoID + "&zoom=" + zoomLevel + "&x=" + x + "&y=" + y;
    }

Parallel.For循环只是为了加快速度,可以用普通的for循环代替。

此方法的唯一问题是,它不适用于以CAoSLEFGMVFpcE开头的全景图。我目前正在尝试为此解决问题,如果找到解决方案,则会更新此答案。

注意:这样做将违反Google的服务条款