2013-02-23 50 views

回答

0

我通过框架的头文件进行搜索,只找到可用于下面的代码,可能是一个开始的接口。这里的问题是,我无法在其他头文件中找到任何GMSCoordinateBounds的导入,所以我找不到在GMSMapView中显示此区域的方法。

GMSVisibleRegion region; 
region.farLeft = CLLocationCoordinate2DMake(farLeftLatitude, farLeftlongitude); 
region.farRight = CLLocationCoordinate2DMake(farRightlatitude, farRightlongitude); 

GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithRegion:region]; 
+0

但是如何设置这个区域的工作? – Mecid 2013-02-25 12:49:28

16

UPDATE:

下原来的答案是过时的的SDK 1.2版本 - 您现在可以使用GMSCameraUpdate类的fitBounds:方法:

https://developers.google.com/maps/documentation/ios/reference/interface_g_m_s_camera_update


原始回答:

MapKit中的MKMapPoint类型定义了地图的2D投影。尽管投影的实际值是不透明的,但它们相当于缩放级别为20的像素。这可用于将经度/纬度值转换为像素,从而将比例转换为缩放比例,从而缩放比例。

首先定义两个位置,指定要显示的区域的边界。这可能是边界框的对角,或只有两个位置,例如:

CLLocationCoordinate2D location1 = 
    CLLocationCoordinate2DMake(-33.8683, 151.2086); // Sydney 
CLLocationCoordinate2D location2 = 
    CLLocationCoordinate2DMake(-31.9554, 115.8585); // Perth 

如果要包括两个以上的点,你可以计算出他们自己的边界。这也可以使用GMSCoordinateBounds完成,例如:

GMSCoordinateBounds* bounds = 
    [[GMSCoordinateBounds alloc] 
    initWithCoordinate: CLLocationCoordinate2DMake(-33.8683, 151.2086) // Sydney 
    andCoordinate: CLLocationCoordinate2DMake(-31.9554, 115.8585)]; // Perth 
bounds = [bounds including: 
    CLLocationCoordinate2DMake(-12.4667, 130.8333)]; // Darwin 
CLLocationCoordinate2D location1 = bounds.southWest; 
CLLocationCoordinate2D location2 = bounds.northEast; 

接下来,你需要获得在点地图视图的大小。你可以使用这个:

float mapViewWidth = _mapView.frame.size.width; 
float mapViewHeight = _mapView.frame.size.height; 

但是,这只会在你已经创建地图视图时才起作用。另外,如果您使用getting started guide中的示例代码,则该帧将设置为CGRectZero,因为稍后将设置实际大小以填充屏幕。在这种情况下,如果你正在创建一个全屏幕的地图,那么你可能想是这样的:

float mapViewWidth = [UIScreen mainScreen].applicationFrame.size.width; 
float mapViewHeight = [UIScreen mainScreen].applicationFrame.size.height; 

否则,使用它你创建你的地图视图大小。

现在你算算相机位置所需的信息:

MKMapPoint point1 = MKMapPointForCoordinate(location1); 
MKMapPoint point2 = MKMapPointForCoordinate(location2); 

MKMapPoint centrePoint = MKMapPointMake(
    (point1.x + point2.x)/2, 
    (point1.y + point2.y)/2); 
CLLocationCoordinate2D centreLocation = MKCoordinateForMapPoint(centrePoint); 

double mapScaleWidth = mapViewWidth/fabs(point2.x - point1.x); 
double mapScaleHeight = mapViewHeight/fabs(point2.y - point1.y); 
double mapScale = MIN(mapScaleWidth, mapScaleHeight); 

double zoomLevel = 20 + log2(mapScale); 

GMSCameraPosition *camera = [GMSCameraPosition 
    cameraWithLatitude: centreLocation.latitude 
    longitude: centreLocation.longitude 
    zoom: zoomLevel]; 

然后,您可以用这台相机初始化地图视图,或设置地图视图这台相机。

为使该代码编译,你需要将MapKit框架添加到您的项目,然后同时导入:

#import <MapKit/MapKit.h> 

请注意,此代码不处理环绕,如果你的坐标跨越越过日期线。例如,如果您尝试在东京和夏威夷使用此代码,而不是显示太平洋地区,它将尝试显示几乎整个世界。在肖像模式下,不可能缩小到足以在左侧看到夏威夷以及在右侧看到东京,因此地图最终以非洲为中心,而两个位置都不可见。如果你愿意的话,你可以修改上面的代码来处理日期行处理。

+0

嗨撒克逊。只要阅读这个答案。难道正确的zoomLevel是“double zoomLevel = 21.0f + log2(mapScale);”。我刚刚在GoogleMaps SDK中查看了最大可能的缩放级别,它似乎是21.0f;顺便说一下,最小缩放级别是2.0f; – 2013-03-06 09:06:27

+0

Hi @ xen100,其中20是在那里,因为'MKMapPoint'相当于缩放级别为20的像素。如果你的边界非常小,那么'mapScale'最终会大于1.0,所以'zoomLevel'会最终结束大于20.如果缩放级别大于SDK的限制,那么它会将缩放级别限制为可支持的级别。 – 2013-03-06 10:03:34

+0

谢谢。这帮了我很多。如果用位置坐标与标记进行边界限制,我建议您稍微减小视图的宽度和高度,以免标记最终位于视图的边缘。 – 2013-03-25 14:39:48

2

我目前正在使用这种方法。

self.markers是一个字典,其中标记存储在一个位置ID中,self.currentLocation是一个CLLocation2D,self.mapView是一个GMSMapView。

这里的数学是检查是否匹配宽度或高度的大小,然后根据x1/pow(2,zoom1)= x2/pow(2,缩放2)”,从而放大2 = LOG 2(X2 * POW(2 self.mapView.camera.zoom)/ X1)。

- (void)fitMarkers 
{ 
    if (2 > self.markers.count) 
    { 
     [self.mapView animateToCameraPosition:[GMSCameraPosition cameraWithTarget:self.currentLocation.coordinate zoom:kZoom]]; 

     return; 
    } 

    NSArray* markers = self.markers.allValues; 

    GMSCoordinateBounds* markerBounds = [[GMSCoordinateBounds alloc] initWithCoordinate:((id<GMSMarker>)markers[0]).position andCoordinate:((id<GMSMarker>)markers[1]).position]; 

    for (id<GMSMarker> marker in markers) 
    { 
     markerBounds = [markerBounds including:marker.position]; 
    } 

    // get marker bounds in points 
    CGPoint markerBoundsTopLeft = [self.mapView.projection pointForCoordinate:CLLocationCoordinate2DMake(markerBounds.northEast.latitude, markerBounds.southWest.longitude)]; 
    CGPoint markerBoundsBottomRight = [self.mapView.projection pointForCoordinate:CLLocationCoordinate2DMake(markerBounds.southWest.latitude, markerBounds.northEast.longitude)]; 

    // get user location in points 
    CGPoint currentLocation = [self.mapView.projection pointForCoordinate:self.currentLocation.coordinate]; 

    CGPoint markerBoundsCurrentLocationMaxDelta = CGPointMake(MAX(fabs(currentLocation.x - markerBoundsTopLeft.x), fabs(currentLocation.x - markerBoundsBottomRight.x)), MAX(fabs(currentLocation.y - markerBoundsTopLeft.y), fabs(currentLocation.y - markerBoundsBottomRight.y))); 

    // the marker bounds centered on self.currentLocation 
    CGSize centeredMarkerBoundsSize = CGSizeMake(2.0 * markerBoundsCurrentLocationMaxDelta.x, 2.0 * markerBoundsCurrentLocationMaxDelta.y); 

    // inset the view bounds to fit markers 
    CGSize insetViewBoundsSize = CGSizeMake(self.mapView.bounds.size.width - kMarkerSize/2.0 - kMarkerMargin, self.mapView.bounds.size.height - kMarkerSize/2.0 - kMarkerSize); 

    CGFloat x1; 
    CGFloat x2; 

    // decide which axis to calculate the zoom level with by comparing the width/height ratios 
    if (centeredMarkerBoundsSize.width/centeredMarkerBoundsSize.height > insetViewBoundsSize.width/insetViewBoundsSize.height) 
    { 
     x1 = centeredMarkerBoundsSize.width; 
     x2 = insetViewBoundsSize.width; 
    } 
    else 
    { 
     x1 = centeredMarkerBoundsSize.height; 
     x2 = insetViewBoundsSize.height; 
    } 

    CGFloat zoom = log2(x2 * pow(2, self.mapView.camera.zoom)/x1); 

    GMSCameraPosition* camera = [GMSCameraPosition cameraWithTarget:self.currentLocation.coordinate zoom:zoom]; 

    [self.mapView animateToCameraPosition:camera]; 
} 
+0

这或多或少是我提出的解决方案。 – 2014-01-07 16:11:50

3

Saxun德鲁斯的答案是真的很好。但除此之外,如果你想从任何位置计算半径,你可以做到这一点与下面的代码:

CLLocationCoordinate2D center = CLLocationCoordinate2DMake([currentLocationLat doubleValue],[currentLocationLong doubleValue]); 
float radius = 25*1000; //radius in meters (25km) 

MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(center, radius*2, radius*2); 

CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(region.center.latitude - region.span.latitudeDelta/2, region.center.longitude - region.span.longitudeDelta/2); 
CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(region.center.latitude + region.span.latitudeDelta/2, region.center.longitude + region.span.longitudeDelta/2); 

GMSCoordinateBounds* bounds = [[GMSCoordinateBounds alloc] 
           initWithCoordinate: northEast 
           andCoordinate: southWest]; 
+0

谢谢! 它确实有效! 最好! – LLIAJLbHOu 2015-05-25 12:02:49

+0

你的答案做我想要的,但你可以添加更多的解释给你的答案? – 2016-02-14 13:05:13

5

UPDATE

所有问题都已在最新版本的Google地图(1.5)中修复。 [mapView_ animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds]];可以noow来代替代码的下方


原来的答案

[GMSCameraUpdate fitBounds]标准方法不会在我的版本的SDK(1.2.0)中给出准确的结果。我正在使用下面的代码而不是它。公式取自Mercator Projection。根据Google Documentation,世界经纬度限制在85度。

#import <stdlib.h> 

-(void) animateBoundsNorth:(CGFloat)north West:(CGFloat)west South:(CGFloat)south East:(CGFloat)east Padding:(int)padding { 

    CGFloat northRad = north * M_PI/180.0; 
    CGFloat northProj = logf(tanf(M_PI_4 + northRad/2.0)); 
    CGFloat southRad = south * M_PI/180.0; 
    CGFloat southProj = logf(tanf(M_PI_4 + southRad/2.0)); 
    CGFloat topRad = 85.0 * M_PI/180.0; 
    CGFloat topProj = logf(tanf(M_PI_4 + topRad/2.0)); 
    CGFloat zoomLat = log2f((mapView_.bounds.size.height - padding * 2) * 2 * topProj /(northProj - southProj)) - 8; 
    CGFloat zoomLon = log2f((mapView_.bounds.size.width - padding * 2) * 360/(east - west)) - 8; 

    GMSCameraUpdate *update = [GMSCameraUpdate setTarget:CLLocationCoordinate2DMake((north+south)/2.0, (west+east)/2.0) zoom:MIN(zoomLat, zoomLon)]; 


    [mapView_ animateWithCameraUpdate:update]; 


} 
+0

我有一个问题。我怎样才能得到“北”,“西”,“南”,“东”和“填充”? – 2013-12-25 07:04:32

+0

这取决于你想要显示的区域 – 2013-12-26 16:32:51

+0

实际上不是,问题还没有解决。我正在使用Google Maps v1.7.2,当我尝试使用GMSCameraUpdate fitBounds方法时,它不起作用。我最终看到地图放大,看到整个北美。我能够正常工作的唯一方法是使用上面的animateWithBoundsNorth:方法。 – Marc 2014-05-01 20:57:10

0

正如2014年6月的,this answer是遍历标记的给定阵列,然后相应地设置边界的最简单方式。

1

按照GoogleMaps的新版本iOS sdk 1.9.2, 我们可以使用Camera的位置,缩放级别,viewingAngle进行设置。

GMSCameraPosition* camera = [GMSCameraPosition cameraWithLatitude:28.6100 
                  longitude:77.2300 
                   zoom:14.0 
                   bearing:0 
                 viewingAngle:0.00]; 
    self.mapView = [GMSMapView mapWithFrame:CGRectMake(0, 45, self.view.frame.size.width, self.view.frame.size.height - 45) camera:camera]; 
    mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

    mapView.delegate = self; 
    mapView.myLocationEnabled = YES; 
    mapView.mapType = kGMSTypeTerrain; 
    mapView.settings.compassButton = YES; 
    mapView.settings.myLocationButton = YES; 
    [self.mapView setMinZoom:10 maxZoom:18]; 

    GMSMarker* marker = [[GMSMarker alloc] init]; 
    marker.position = CLLocationCoordinate2DMake(28.6100, 77.2300); 
    marker.title = @"New Delhi"; 
    marker.snippet = @"Capital Of India"; 

    marker.map = self.mapView; 
    marker.appearAnimation = kGMSMarkerAnimationPop; 
    marker.icon = [GMSMarker markerImageWithColor:[UIColor grayColor]]; 
    [self.view addSubview:self.mapView]; 

有关进一步的参考see this PDF document

你还可以设置最小和最大缩放级别根据自己的需要:

[self.mapView setMinZoom:10 maxZoom:30]; 

希望这解决了这个问题。

3

如果你有“极左”和谷歌地图的“接近权”的角落,你可以使用下面的代码

 var region:GMSVisibleRegion = GMSVisibleRegion() 
    region.nearLeft = CLLocationCoordinate2DMake(nearleflat, nearleftlong) 
    region.farRight = CLLocationCoordinate2DMake(fareastlat,fareastlong) 
    let bounds = GMSCoordinateBounds(coordinate: region.nearLeft,coordinate: region.farRight) 
    let camera = googleMapView.cameraForBounds(bounds, insets:UIEdgeInsetsZero) 
    googleMapView.camera = camera; 

This链接也可能会显示在SWIFT数据的纬度和经度有助于相关的事情。

+1

这可以帮助我迅速。但我得到的两点几乎超出了屏幕,我怎么能得到更多的中心两点:nearLeft和farRight ?.谢谢你的帮助! – Dasoga 2016-01-28 00:17:58

+0

我尝试了很多使用其他技术 – 2016-09-06 12:51:04

0

//我发现这个方法对我来说

func setMapZoomToRadius(lat:Double, lng:Double, var mile:Double) 
    { 

     let center = CLLocationCoordinate2DMake(lat, lng)   
     let radius: Double = (mile) * 621.371 

     let region = MKCoordinateRegionMakeWithDistance(center, radius * 2.0, radius * 2.0) 


     let northEast = CLLocationCoordinate2DMake(region.center.latitude - region.span.latitudeDelta, region.center.longitude - region.span.longitudeDelta) 
     let southWest = CLLocationCoordinate2DMake(region.center.latitude + region.span.latitudeDelta, region.center.longitude + region.span.longitudeDelta) 


     print("\(region.center.longitude) \(region.span.longitudeDelta)") 
     let bounds = GMSCoordinateBounds(coordinate: southWest, coordinate: northEast) 

     let camera = googleMapView.cameraForBounds(bounds, insets:UIEdgeInsetsZero) 
     googleMapView.camera = camera; 

     }