我正在尝试请求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。
感谢任何想法,谢谢。 :)
答案 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的服务条款