有人知道一个公式,我可以用它来转换从谷歌地图缩放Android API:https://developers.google.com/maps/documentation/android-api/streetview到谷歌街景图像API中使用的FOV:https://developers.google.com/maps/documentation/streetview/intro?
我在这里找到了几个旧公式:
然后,我对他们进行了测试,在我的android手机上缩放相机时,会计算FOV:
FOV1:3.9018*Math.pow(StreetViewPanoramaCamera.zoom,2) - 42.432*StreetViewPanoramaCamera.zoom123
FOV2:数学。abs(街景全景摄像头。变焦/5*108-120
FOV3:180/数学。pow(2,街景全景摄像头。缩放)
@Override
public void onStreetViewPanoramaCameraChange(StreetViewPanoramaCamera streetViewPanoramaCamera) {
Log.e("Pano", "Bearing: " + streetViewPanoramaCamera.bearing + " Tilt: " + streetViewPanoramaCamera.tilt +
" Zoom: " + streetViewPanoramaCamera.zoom +
" FOV1: "+ String.valueOf(3.9018*Math.pow(streetViewPanoramaCamera.zoom,2) - 42.432*streetViewPanoramaCamera.zoom + 123) +" FOV2: "+
Math.abs(streetViewPanoramaCamera.zoom/5*108-120) +" FOV3: "+ 180/Math.pow(2,streetViewPanoramaCamera.zoom) ) ;
}
在Android上缩放0.0,我们返回以下FOV值:
09-27 15:53:52.322东/帕诺﹕ 方位:228.28955倾斜:14.516191变焦:0.0FOV1:123.0FOV2:120.0FOV3:180.0
由于FOV的最大值为120,FOV2的公式起初似乎很有希望,但当我放大2倍时,它给出的值为76.8,这与实际值相差甚远:
09-27 16:01:48.235东/帕诺﹕ 方位:223.11241倾斜:1.852709变焦:2.0 FOV1:53.7432 FOV2:76.8 FOV3:45.0
这是我手机经过两次缩放后的图像:
这是从FOV 76.8的谷歌街景图像API下载的图像(https://maps.googleapis.com/maps/api/streetview?size=600x300
这是从FOV 45的谷歌街景图像API下载的图像(https://maps.googleapis.com/maps/api/streetview?size=600x300
我得到的最接近的是如果我做了FOV 26,但那是我猜测的,没有使用公式——下面的图片是FOV 26:
在谷歌上搜索这个答案,我只能找到网络的公式。网络不同,因为首先,在留档中有一个缩放和视场图表:https://developers.google.com/maps/documentation/javascript/streetview#TilingPanoramas
因此我们可以想出一个公式。Android文档中没有这样的表格,人们在web上使用的公式也不适用于Android(甚至不接近)。
不过也有一些好消息,Android API中提供了这个功能:StreetViewPanorama。方向点(街景全景方向)
这个函数允许我们提供一个方向,它将返回屏幕上该方向所在的点。这个函数的文档说,如果方向离开屏幕,它将返回null,但在实践中,我发现它将给出屏幕可视区域之外的一个点;然而,如果我们知道屏幕尺寸,我们可以检查该点是否有效。通过180度的循环,我们可以发现该范围内有多少区域是可见的,因此视野也是可见的。
警告:此功能效率低下。只有当变焦改变时才打电话!
注:下面的示例代码计算水平视野。要计算垂直视野,需要进行一些更改。例如,改变点。x指向点。y、 更改屏幕大小的所有实例。x到屏幕大小。y、 更改街景全景摄像头的所有实例。指向街景全景摄像头。倾斜,并更改以下所有实例:
orientation = new StreetViewPanoramaOrientation(streetViewPanoramaCamera.tilt, angleCheck);
至:
orientation = new StreetViewPanoramaOrientation(angleCheck, streetViewPanoramaCamera.bearing);
这里是一个简单的方法,我们只需从-90度循环到90度,看看180度中有多少在可视区域(注意:这只适用于倾斜为0度的情况,即用户没有向上或向下看):
private StreetViewPanorama mStreetViewPanorama;
private float mZoom = -1f;
private int mFieldOfViewDegrees;
private void onOrientationUpdate(StreetViewPanoramaCamera streetViewPanoramaCamera) {
if (streetViewPanoramaCamera.zoom != mZoom) {
mFieldOfViewDegrees = getFieldOfView(streetViewPanoramaCamera);
mZoom = streetViewPanoramaCamera.zoom;
}
}
private int getFieldOfView(StreetViewPanoramaCamera streetViewPanoramaCamera) {
WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
StreetViewPanoramaOrientation orientation;
Integer lowerFovDegrees = null;
Integer upperFovDegrees = null;
for (int angleCheck = (int) streetViewPanoramaCamera.bearing - 90;
angleCheck <= (int) streetViewPanoramaCamera.bearing + 90;
angleCheck++) {
orientation = new StreetViewPanoramaOrientation(streetViewPanoramaCamera.tilt, angleCheck);
Point point = mStreetViewPanorama.orientationToPoint(orientation);
if (lowerFovDegrees == null) {
if ((point != null) && (point.x >= 0)) {
lowerFovDegrees = angleCheck;
}
} else if (upperFovDegrees == null) {
if ((point == null) || (point.x > screenSize.x)) {
upperFovDegrees = angleCheck - 1;
break;
}
}
}
int fieldOfViewDegrees = upperFovDegrees - lowerFovDegrees;
return fieldOfViewDegrees;
}
然而,OrientationPoint()非常昂贵,它最多可以调用180次。我们可以使用二进制搜索来提高效率(尽管更复杂),并将其减少到大约13个调用。在本例中,我使用了递归函数来执行二进制搜索。此外,还存在一个限制,即水平赤道必须在视野范围内,否则无法准确计算FOV;在本例中,它返回null。只要用户没有一直向下或向上倾斜,这不是一个真正的问题,但如果他们这样做,FOV将返回null,您需要隐藏任何依赖于FOV是否准确的UI元素(否则它们将不在正确的位置)。
private StreetViewPanorama mStreetViewPanorama;
private float mZoom = -1f;
private float mFieldOfViewDegrees;
private void onOrientationUpdate(StreetViewPanoramaCamera streetViewPanoramaCamera) {
if (streetViewPanoramaCamera.zoom != mZoom) {
Float fieldOfViewDegrees = getFieldOfView(streetViewPanoramaCamera);
if (fieldOfViewDegrees == null) { // If FOV cannot be determined, hide any overlay UI overlay elements so they don't display misaligned
mZoom = -1f;
// Hide UI overlay elements
} else {
mFieldOfViewDegrees = fieldOfViewDegrees;
mZoom = streetViewPanoramaCamera.zoom;
// Show UI overlay elements
}
}
}
/*
* Determine field of view. Must use roundabout way since the info is not provided directly.
* StreetViewPanorama.orientationToPoint() will tell us if a particular orientation is visible on the
* screen, so we can loop from looking left (-90) to right (+90) and see how much of the 180 degrees is in
* the field of view.
*
* This is is CPU intensive, so instead of a simple loop we use a recursive binary search, and make sure
* to only call this function when the zoom has changed.
*
* WARNING: This method of getting the FOV only works if the equator is still in view. If the user tilts
* too far down or up, it will return null.
*/
private Float getFieldOfView(StreetViewPanoramaCamera streetViewPanoramaCamera) {
WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
// If the equator is no longer in view, FOV cannot be accurately calculated
StreetViewPanoramaOrientation orientation =
new StreetViewPanoramaOrientation(0, streetViewPanoramaCamera.bearing);
Point point = mStreetViewPanorama.orientationToPoint(orientation);
if (point.y < 0 || point.y > screenSize.y) {
return null;
}
Float lowerFovDegrees = getLowerFieldOfViewDegrees(
streetViewPanoramaCamera,
screenSize,
streetViewPanoramaCamera.bearing - 90f,
streetViewPanoramaCamera.bearing + 90f);
Float upperFovDegrees = getUpperFieldOfViewDegrees(
streetViewPanoramaCamera,
screenSize,
streetViewPanoramaCamera.bearing - 90f,
streetViewPanoramaCamera.bearing + 90f);
if ((lowerFovDegrees == null) || (upperFovDegrees == null)) return null;
float fieldOfViewDegrees = upperFovDegrees - lowerFovDegrees;
return fieldOfViewDegrees;
}
// Recursive binary search function
private Float getLowerFieldOfViewDegrees(StreetViewPanoramaCamera streetViewPanoramaCamera,
Point screenSize,
float startDegrees,
float endDegrees) {
StreetViewPanoramaOrientation orientation;
float midpointDegrees = (int) (startDegrees + ((endDegrees - startDegrees) / 2f));
orientation = new StreetViewPanoramaOrientation(0, midpointDegrees);
Point point = mStreetViewPanorama.orientationToPoint(orientation);
if ((point == null) || (point.x < 0)) {
if (endDegrees - midpointDegrees <= 1f) {
return endDegrees;
}
return getLowerFieldOfViewDegrees(
streetViewPanoramaCamera,
screenSize,
midpointDegrees,
endDegrees);
} else {
if (midpointDegrees - startDegrees <= 1f) {
return midpointDegrees;
}
return getLowerFieldOfViewDegrees(
streetViewPanoramaCamera,
screenSize,
startDegrees,
midpointDegrees);
}
}
// Recursive binary search function
private Float getUpperFieldOfViewDegrees(StreetViewPanoramaCamera streetViewPanoramaCamera,
Point screenSize,
float startDegrees,
float endDegrees) {
StreetViewPanoramaOrientation orientation;
float midpointDegrees = (int) (startDegrees + ((endDegrees - startDegrees) / 2f));
orientation = new StreetViewPanoramaOrientation(0, midpointDegrees);
Point point = mStreetViewPanorama.orientationToPoint(orientation);
if ((point == null) || (point.x > screenSize.x)) {
if (midpointDegrees - startDegrees <= 1f) {
return startDegrees;
}
return getUpperFieldOfViewDegrees(
streetViewPanoramaCamera,
screenSize,
startDegrees,
midpointDegrees);
} else {
if (endDegrees - midpointDegrees <= 1f) {
return midpointDegrees;
}
return getUpperFieldOfViewDegrees(
streetViewPanoramaCamera,
screenSize,
midpointDegrees,
endDegrees);
}
}
上面函数的粒度是最接近的程度。你可以修改它以给出更小的粒度,但是它需要更长的时间来运行。由于它已经会导致图形结巴,我没有这样做。
我希望这对其他人有所帮助,因为这似乎是一个常见的问题,我还没有看到Android解决了这个问题。
您可以使用以下公式(JavaScript代码):
>
将视野转换为缩放:
缩放=Math.log(180/fov
)/(Math.log(2))
将缩放转换为视野:
fov=180/数学。pow(2,
缩放
)
最后,我不得不倒退这条线来得到指数公式。
我使用这个网站,手动输入FOV和缩放值的数据点组合,这些数据点很好地结合在一起:http://www.had2know.com/academics/regression-calculator-statistics-best-fit.html
我的数据点是:
视野(放大视野旁边的括号)
120 (0)
50(1)
45(1.2)
37(1.5)
26 (2)
69 (0.5)
78 (0.3)
31 (1.9)
为了得到一个更接近的公式,你可以不断地添加更多“合适”的数据点,但我只是没有时间——任何想完善这个公式的人都可以尝试。
我得到了下面的公式,其中Y是视场,X是变焦。
Y=103.7587(0.5051^X)
相关性=-0.9882
我需要完全按照用户选择的方式保存街景图像(包括全景、航向、俯仰和视野)。我有以下代码: 问题是我想保存缩放为fov值https://developers.google.com/maps/documentation/streetview/intro(看fov可选参数) fov(默认值为90)确定图像的水平视野。视野以度表示,最大允许值为120。当处理固定大小的视口时,就像处理设置大小的街景图像一样,
我正在尝试使用谷歌街景API获取街景图像。我的代码适用于除法国以外的所有国家。出于某种原因,当我试图从法国任何地方获取数据时,我只会得到一张灰色图像,上面写着“对不起,我们这里没有图像。”但是,我知道那里有图像,因为我可以通过你的谷歌网站使用谷歌街景,看到街景。 例如,如果我去https://maps.google.com/maps/ms?ie=UTF8 知道我做错了什么吗?为什么会这样?
我们使用谷歌街景图像应用编程接口(而不是Javascript应用编程接口)来构建一个返回街景图像的网址。问题是,有时它会返回建筑物内部的图像,而不是提供地址的建筑物图像,例如: https://maps.googleapis.com/maps/api/streetview?size=600x300 是否有只显示户外图像的解决方案/解决方法?
我知道可以使用谷歌API视觉在网上找到类似的图片。我的目标是根据我的图像数据库找到类似的图像。我不想在网上看到类似的图片。 可能吗? 如果是,你能给我一些链接或建议吗? 谢谢
问题内容: 说我有一个这样定义的: 根据我的阅读 (如果我错了,请纠正我): 如果将值写入0:00,则应在60秒后将其移至“准备退出”状态。从中实际删除值将在下一次 缓存修改 时发生(究竟是什么缓存修改?)。 那正确吗? 另外,我不确定和方法之间有什么区别,有人可以提供解释吗? 问题答案: *此链接的 *第一部分 :Guava如何使CacheBuilder中的条目到期? 我将重点讨论 expire
我对谷歌地图API完全是个新手,我想开发一款将谷歌地图上的街道作为路径的游戏。我很清楚我需要什么,但我甚至不知道从API文档中开始搜索什么。。。 如何获得城市街道或谷歌地图其他部分的图形表示,例如交叉点的顶点和边的街道名称(或任何我可以转换为类似的内容),并将顶点映射到(lat,long)协调点…甚至街道的多段线对象,以便从中提取所需内容?(路由查找算法当然可以访问这样的数据结构,所以它就在那里的