- 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/
我正在使用 Selenium Web 驱动程序 3.0,并且想要从打开的两个对话框(一个在后台,第二个在前台)的 Activity 对话框中单击“确定”按钮。如何从 html 下面的父 div 单击前
actions: [ FlatButton( onPressed: () {
我有一个问题有点超出我的范围(我真的很高兴我是 Beta)涉及重复项(所以 GROUP BY, HAVING, COUNT),通过将解决方案保留在 SQLite 附带的标准函数中而变得更加复杂。我正在
使用DBI是否可以确定SELECT语句的已执行语句句柄是否返回任何行而不从中获取行? IE。就像是: use DBI; ... my $sth = $dbh->prepare("SELECT ..."
是否可以为“确定”和“关闭”按钮指定回调函数? 如果是JQuery Modal,则可以在初始化时使用按钮字典指定回调函数。 Semantic-ui模态是否提供类似的功能?按下确定后,我该如何寻求其他逻
我想阅读警报中的消息。 示例:如果警报显示“错误的电子邮件地址”。怎么读呢?意味着我想将该消息存储在字符串中。 如何在“警报”中单击“确定”...?? 如何使用 Selenium 来做到这一点? 最佳
我有一个删除按钮: 我试图首先查明是否已选择一个网站,如果已选择一个网站,我需要确定是否已选择一个或多个列表项,如果是,则继续删除这些项目。 我的 if 语句不断返回“您必须首先选择您的列表”,即使它
部分出于好奇——我们想知道在我们的应用程序中发生了什么——部分是因为我们需要在我们的代码中找到一些潜在的问题,我喜欢在我们的网络应用程序运行时跟踪一些一般值。这尤其包括某些对象图的分配内存。 我们的应
我将 SweetAlert 与 Symfony 结合使用,我希望用户在完成删除操作之前进行确认。 发生的情况是,当用户单击删除按钮时,SweetAlert 会弹出,然后立即消失,并且该项目被删除。 在
我们有一个应用程序可以生成不包括字母 O 的随机基数 35 [0-9A-Z]。我正在寻找一种解决方案来查找包含任何淫秽英语单词的代码,而无需搜索包含 10,000 个条目的列表每个生成的代码。每秒生成
这是我做的: #include #include int betweenArray(int a, int b){ int *arr,i,range; range = b - a +
我知道如何创建 警报和确认框,但我不知道如何做的是实际单击“确定”。我有一个弹出确认框的页面。 我想使用 Java Script 插件单击“确定”。基本上,我希望我的代码单击页面上的链接,然后在出现提
代码: swal('Your ORDER has been placed Successfully!!!'); window.location="index.php"; 甜蜜警报工
>>> import re >>> s = "These are the words in a sentence" >>> regex = re.compile('are|words') >>> [m
使用确定的理想散列函数给出随机期望线性时间算法两个数组 A[1..n] 和 B[1..n] 是否不相交,即 A 的元素是否也是 B 的元素。 谁能告诉我如何做到这一点,甚至如何开始考虑它? 最佳答案
我在计算机科学课上有这段代码: int input=15; while (input < n ) { input = input *3;} 这段代码有 log3(n/15) 次循环的上限。我们怎样才能
我有一个允许 2 位玩家玩 TicTacToe 的程序。在每个玩家移动之后,它应该在那个点显示棋盘并返回一个名为 Status 的枚举,显示玩家是否应该继续,如果玩家赢了,还是平局。但是,该算法要么返
给定一个 y 值数组,例如 [-3400, -1000, 500, 1200, 3790],我如何确定“好的”Y 轴标签并将它们放置在网格上? ^ ---(6,000)-|---
假设我有一个检查用户登录的 SQL 语句: SELECT * FROM users WHERE username='test@example.com', password='abc123', expi
teradata中有返回表中哪一列被定义为主索引的命令吗?我没有制作一些我正在处理的表,也没有尝试优化我对这些表的连接。谢谢! 最佳答案 有dbc.IndicesV,其中IndexNumber=1表示
我是一名优秀的程序员,十分优秀!