- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我需要弄清楚如何设置 MKMapSnapshotterOptions 来拍摄与地球多边形区域相关的航空/卫星图像快照。
填写“区域”、“比例”、“大小”和“mapType”属性很简单,因为我有一个 MKPolygon 可以使用。棘手的部分是设置“相机”——在我的特定情况下,我正在独立于 MKMapView 使用 MKMapSnapshotter(事实上,甚至不在主线程上)。
但是,我更愿意调整快照的方向,使其适合基于非零航向的多边形边界——也就是说,我正在拍照的区域有一个“开始”和一个“end',我想从结果图像的底部到顶部定位。由于多边形基本上永远不会以 0 度航向自然定向,因此我需要确定“centerCoordinate”、“heading”和“altitude”。
因为我有多边形的坐标,所以我能够很容易地得出中心坐标和所需的航向——多边形的第一个坐标与形状的“开始”和结束(或其他坐标,在我的case) 与“结束”相关。
事实证明,确定海拔高度更加困难;我想确保多边形区域最终填充我希望显示的快照图像的纵横比。如何在不依赖 MKMapView 的“setRegion”选择器的情况下计算与 MKMapCamera 一起使用的正确高度?
最佳答案
为了解决这个问题,我最终做了以下事情:
1) 在确定边界矩形时围绕其中心坐标旋转 MKPolygon 以消除航向/旋转问题:询问 MKPolygon 是否为“boundingMapRect”,如果没有这个,将返回适合整个形状的任何最小矩形。如果一个又长又瘦的多边形恰好从东北向西南呈对角线方向,则边界矩形将接近正方形。执行旋转允许在确定其纵横比时考虑多边形的方向。
2) 将多边形的航向校正边界矩形调整为快照视口(viewport)的纵横比:这可确保非常“高”的多边形仍能正确适合广角视口(viewport),反之亦然。
3)[从我的示例代码中删除] 创建一个多边形的纵横比校正边界矩形并使用多边形的中心坐标将其旋转回原始航向:如果使用大区域,因为下一步涉及水平/垂直边界距离之间的测量。就我而言,我正在处理非常小的区域,这些区域不应受到地球曲率的足够影响而不会产生真正的影响。
4) 确定以米为单位的总水平和垂直边界区域
5) 使用两个距离中较大的维度(Dimension)形成三角形的基础测量,其中A = 轴上的最小坐标位置,B = 轴上的最大坐标位置,C = 相机位置(中心坐标的多边形)
在这一点上,我对如何在没有至少 1 个角的情况下求解所得三角形的高度感到有点困惑。在使用 MKMapView 实例执行一些测试时,MKMapCamera 的孔径似乎约为 30 度——这与增加视口(viewport)的纵横比、多边形的纵横比或任何其他方面无关除了地球曲率之外的其他因素。我对这个断言可能是错误的。
5) 使用我在测试中观察到的孔径角,使用 (dimension/2)/tan(aperture_angle_in_radians/2) 计算所需的高度
看到我最终花了多少时间在这上面,我决定在 StackOverflow 上发布问题/答案组合,希望它:1)帮助处于相同情况的其他人2) 被比我更聪明的人纠正并导致更好的解决方案
谢谢!
哦,当然还有代码:
+ (double)determineAltitudeForPolygon:(MKPolygon *)polygon withHeading:(double)heading andWithViewport:(CGSize)viewport {
// Get a bounding rectangle that encompasses the polygon and represents its
// true aspect ratio based on the understanding of its heading.
MKMapRect boundingRect = [[self rotatePolygon:polygon withCenter:MKMapPointForCoordinate(polygon.coordinate) byHeading:heading] boundingMapRect];
MKCoordinateRegion boundingRectRegion = MKCoordinateRegionForMapRect(boundingRect);
// Calculate a new bounding rectangle that is corrected for the aspect ratio
// of the viewport/camera -- this will be needed to ensure the resulting
// altitude actually fits the polygon in view for the observer.
CLLocationCoordinate2D upperLeftCoord = CLLocationCoordinate2DMake(boundingRectRegion.center.latitude + boundingRectRegion.span.latitudeDelta / 2, boundingRectRegion.center.longitude - boundingRectRegion.span.longitudeDelta / 2);
CLLocationCoordinate2D upperRightCoord = CLLocationCoordinate2DMake(boundingRectRegion.center.latitude + boundingRectRegion.span.latitudeDelta / 2, boundingRectRegion.center.longitude + boundingRectRegion.span.longitudeDelta / 2);
CLLocationCoordinate2D lowerLeftCoord = CLLocationCoordinate2DMake(boundingRectRegion.center.latitude - boundingRectRegion.span.latitudeDelta / 2, boundingRectRegion.center.longitude - boundingRectRegion.span.longitudeDelta / 2);
CLLocationDistance hDist = MKMetersBetweenMapPoints(MKMapPointForCoordinate(upperLeftCoord), MKMapPointForCoordinate(upperRightCoord));
CLLocationDistance vDist = MKMetersBetweenMapPoints(MKMapPointForCoordinate(upperLeftCoord), MKMapPointForCoordinate(lowerLeftCoord));
double adjacent;
double newHDist, newVDist;
if (boundingRect.size.height > boundingRect.size.width) {
newVDist = vDist;
newHDist = (viewport.width / viewport.height) * vDist;
adjacent = vDist / 2;
} else {
newVDist = (viewport.height / viewport.width) * hDist;
newHDist = hDist;
adjacent = hDist / 2;
}
double result = adjacent / tan(Deg_to_Rad(15));
return result;
}
+ (MKPolygon *)rotatePolygon:(MKPolygon *)polygon withCenter:(MKMapPoint)centerPoint byHeading:(double)heading {
MKMapPoint points[polygon.pointCount];
double rotation_angle = -Deg_to_Rad(heading);
for(int i = 0; i < polygon.pointCount; i++) {
MKMapPoint point = polygon.points[i];
// Translate each point by the coordinate to rotate around, use matrix
// algebra to perform the rotation, then translate back into the
// original coordinate space.
double newX = ((point.x - centerPoint.x) * cos(rotation_angle)) + ((centerPoint.y - point.y) * sin(rotation_angle)) + centerPoint.x;
double newY = ((point.x - centerPoint.x) * sin(rotation_angle)) - ((centerPoint.y - point.y) * cos(rotation_angle)) + centerPoint.y;
point.x = newX;
point.y = newY;
points[i] = point;
}
return [MKPolygon polygonWithPoints:points count:polygon.pointCount];
}
关于ios - 如何确定聚焦于 MKPolygon 的 MKMapCamera 的正确高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21034409/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!