Rob*_*ndl 3 google-maps ios clregion google-maps-sdk-ios
我正在使用GoogleMaps SDK,目前我正在尝试将GMSVisibleRegion转换为CLRegion.
GMSVisibleRegion定义为:
typedef struct {
CLLocationCoordinate2D nearLeft;
CLLocationCoordinate2D nearRight;
CLLocationCoordinate2D farLeft;
CLLocationCoordinate2D farRight;
} GMSVisibleRegion;
Run Code Online (Sandbox Code Playgroud)
最快的方法是什么?
不幸的是,很难理解开发人员在命名"near"和"far"时的含义.我认为这个评论也很有用:
/**
* Returns the region (four location coordinates) that is visible according to
* the projection.
*
* The visible region can be non-rectangular. The result is undefined if the
* projection includes points that do not map to anywhere on the map (e.g.,
* camera sees outer space).
*/
- (GMSVisibleRegion)visibleRegion;
Run Code Online (Sandbox Code Playgroud)
非常感谢!
编辑:好的,我的第一步是创建一个GMSVisibleRegion的MKCoordinateRegion.
我建议使用以下代码将GMSVisibleRegion转换为MKCoordinateRegion.任何异议.
+ (MKCoordinateRegion)regionForCenter:(CLLocationCoordinate2D)center andGMSVisibleRegion:(GMSVisibleRegion)visibleRegion
{
CLLocationDegrees latitudeDelta = visibleRegion.farLeft.latitude - visibleRegion.nearLeft.latitude;
CLLocationDegrees longitudeDelta = visibleRegion.farRight.longitude - visibleRegion.farLeft.longitude;
MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
return MKCoordinateRegionMake(center, span);
}
Run Code Online (Sandbox Code Playgroud)
Sax*_*uce 11
我的猜测是"靠近"是屏幕底部视图的角落,"远"是指屏幕顶部的角落.这是因为如果您倾斜视图,则底角最靠近相机,顶角距离相机最远.
将其转换为a的一种方法CLRegion可能是使用相机的目标作为中心,然后计算从最大距离到四个角的半径.这可能不是该区域上最紧密的拟合圆,但由于圆不能适合视图的四边形,所以它可能足够接近.
这是一个辅助函数,用于计算两个CLLocationCoordinate值之间的距离(米):
double getDistanceMetresBetweenLocationCoordinates(
CLLocationCoordinate2D coord1,
CLLocationCoordinate2D coord2)
{
CLLocation* location1 =
[[CLLocation alloc]
initWithLatitude: coord1.latitude
longitude: coord1.longitude];
CLLocation* location2 =
[[CLLocation alloc]
initWithLatitude: coord2.latitude
longitude: coord2.longitude];
return [location1 distanceFromLocation: location2];
}
Run Code Online (Sandbox Code Playgroud)
然后CLRegion可以像这样计算:
GMSMapView* mapView = ...;
...
CLLocationCoordinate2D centre = mapView.camera.target;
GMSVisibleRegion* visibleRegion = mapView.projection.visibleRegion;
double nearLeftDistanceMetres =
getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.nearLeft);
double nearRightDistanceMetres =
getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.nearRight);
double farLeftDistanceMetres =
getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.farLeft);
double farRightDistanceMetres =
getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.farRight);
double radiusMetres =
MAX(nearLeftDistanceMetres,
MAX(nearRightDistanceMetres,
MAX(farLeftDistanceMetres, farRightDistanceMetres)));
CLRegion region = [[CLRegion alloc]
initCircularRegionWithCenter: centre radius: radius identifier: @"id"];
Run Code Online (Sandbox Code Playgroud)
更新:
关于您的更新MKCoordinateRegion,您的示例代码可能无法正常工作.如果地图已经旋转了90度,然后farLeft和nearLeft将具有相同的纬度,并farRight与farLeft具有相同的经度,所以你的经度和纬度增量为零.
你会需要循环的所有四个farLeft,farRight,nearLeft,nearRight,计算每个的纬度和经度的最小值和最大值,然后从计算的增量.
适用于iOS的Google Maps SDK包含一个帮助程序类,已经为您完成了一些帮助GMSCoordinateBounds.它可以用以下内容初始化GMSVisibleRegion:
GMSMapView* mapView = ...;
....
GMSVisibleRegion visibleRegion = mapView.projection.visibleRegion;
GMSCoordinateBounds bounds =
[[GMSCoordinateBounds alloc] initWithRegion: visibleRegion];
Run Code Online (Sandbox Code Playgroud)
在GMSCoordinateBounds于是具有northEast和southWest其限定的边界特性.所以你可以按如下方式计算增量:
CLLocationDegrees latitudeDelta =
bounds.northEast.latitude - bounds.southWest.latitude;
CLLocationDegrees longitudeDelta =
bounds.northEast.longitude - bounds.southWest.longitude;
Run Code Online (Sandbox Code Playgroud)
您还可以从边界计算中心,因此MKCoordinateRegion:
CLLocationCoordinate2D centre = CLLocationCoordinate2DMake(
(bounds.southWest.latitude + bounds.northEast.latitude) / 2,
(bounds.southWest.longitude + bounds.northEast.longitude) / 2);
MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
return MKCoordinateRegionMake(centre, span);
Run Code Online (Sandbox Code Playgroud)
纯粹主义者的附录
如果你想要非常严格,那么你需要在国际日期线上进行修正.大多数应用程序都会浪费精力,但这个问题一直让我感到非常悲痛,所以我想把它扔进社区帽子里
以Druce的更新为基础(害怕我无法发表评论)......
GMSMapView* mapView = ...;
....
GMSVisibleRegion visibleRegion = mapView.projection.visibleRegion;
GMSCoordinateBounds bounds =
[[GMSCoordinateBounds alloc] initWithRegion: visibleRegion];
Run Code Online (Sandbox Code Playgroud)
纬度不需要做任何事情
CLLocationDegrees latitudeDelta =
bounds.northEast.latitude - bounds.southWest.latitude;
Run Code Online (Sandbox Code Playgroud)
该交易涉及跨越国际日期线的地区可能在日本的西南角(经度+140)和其在阿拉斯加的东北角(经度-150).加起来除以2可以得出全球错误的一面.
northEast.longitude小于southWest.longitude的特殊情况需要处理
CLLocationCoordinate2D centre;
CLLocationDegrees longitudeDelta;
if(bounds.northEast.longitude >= bounds.southWest.longitude) {
//Standard case
centre = CLLocationCoordinate2DMake(
(bounds.southWest.latitude + bounds.northEast.latitude) / 2,
(bounds.southWest.longitude + bounds.northEast.longitude) / 2);
longitudeDelta = bounds.northEast.longitude - bounds.southWest.longitude;
} else {
//Region spans the international dateline
centre = CLLocationCoordinate2DMake(
(bounds.southWest.latitude + bounds.northEast.latitude) / 2,
(bounds.southWest.longitude + bounds.northEast.longitude + 360) / 2);
longitudeDelta = bounds.northEast.longitude + 360
- bounds.southWest.longitude;
}
MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
return MKCoordinateRegionMake(centre, span);
Run Code Online (Sandbox Code Playgroud)
根据 @Saxon Druce 的回答,这是设置和获取region使用 MKCooperativeRegion 的快速扩展GMSMapView
extension GMSMapView {
var region : MKCoordinateRegion {
get {
let position = self.camera
let visibleRegion = self.projection.visibleRegion()
let bounds = GMSCoordinateBounds(region: visibleRegion)
let latitudeDelta = bounds.northEast.latitude - bounds.southWest.latitude
let longitudeDelta = bounds.northEast.longitude - bounds.southWest.longitude
let center = CLLocationCoordinate2DMake(
(bounds.southWest.latitude + bounds.northEast.latitude) / 2,
(bounds.southWest.longitude + bounds.northEast.longitude) / 2)
let span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta)
return MKCoordinateRegionMake(center, span)
}
set {
let northEast = CLLocationCoordinate2DMake(newValue.center.latitude - newValue.span.latitudeDelta/2, newValue.center.longitude - newValue.span.longitudeDelta/2)
let southWest = CLLocationCoordinate2DMake(newValue.center.latitude + newValue.span.latitudeDelta/2, newValue.center.longitude + newValue.span.longitudeDelta/2)
let bounds = GMSCoordinateBounds(coordinate: northEast, coordinate: southWest)
let update = GMSCameraUpdate.fitBounds(bounds, withPadding: 0)
self.moveCamera(update)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6411 次 |
| 最近记录: |