有了 Maps SDK for iOS,您可以變更地圖的相機,變更使用者查看地圖的視角。
有了 Maps SDK for iOS,使用者可以傾斜和旋轉地圖,將地圖調整為實用的方向。在任何縮放等級下,使用者都能平移地圖或變更其視角,而且延遲時間極短。
調整相機不會變更已新增的標記、折線或其他圖形,不過建議您配合新視角修改這些新增內容。
地圖的視圖
Maps SDK for iOS 使用麥卡托投影,在裝置螢幕 (平面上) 上代表世界表面 (球體)。
攝影機位置
地圖檢視是模擬向下俯瞰平面的攝影機。攝影機的位置 (以及連帶的地圖算繪方式) 是由下列屬性來指定:目標 (經緯度位置)、航向、傾斜角度和縮放。
目標 (位置)
攝影機目標是地圖的中心位置,透過經緯度座標指定。
緯度可以介於正負 85 度 (含首尾)。只要超出這個範圍,都會調整為範圍內最接近的值。舉例來說,如果將緯度指定為 100,值就會設為 85。經度的範圍介於正負 180 度 (含首尾)。凡是超出這個範圍,都會換算為範圍 (正負 180) 內的值。舉例來說,480、840 和 1200 都會換算為 120 度。航向 (方向)
攝影機航向指的是指南針方向 (以度為單位,從正北算起,對應至地圖頂端邊緣)。如果您從地圖的中心點到頂端邊緣繪製一條垂直線,航向會對應到相對於正北的攝影機方向 (以度為單位)。
航向 0 表示地圖頂端指向正北。航向值 90 表示地圖頂端朝向正東 (在指南針上顯示為 90 度),航向值 180 表示地圖頂端朝向正南。
Maps API 能讓您改變地圖的航向。舉例來說,駕駛人為了讓道路地圖和行進方向一致,常會翻轉地圖;健行的人如果把地圖和指南針搭配使用,通常會將地圖上的垂直線對準北方。
傾斜角度 (視角)
傾斜角度是指在地圖中心位置正上方的弧線上,從天底 (攝影機正下方) 測量至攝影機鏡頭位置所得的角度。值為 0 時,攝影機朝向正下方。值大於 0 時,攝影機依指定角度朝地平線傾斜。視角改變時,地圖的呈現會按照透視法調整,較遠的地圖項目看起來較小,鄰近的地圖項目看起來則較大。請參閱下方範例的說明。
在下圖中,視角為 0 度。第一張是相關示意圖,1 是攝影機位置,2 則是目前地圖的位置。最終地圖則如下所示。
在下圖中,視角為 45 度。請注意,攝影機沿著弧線移動到地圖正上方 (0 度) 和地面 (90 度) 中間,也就是 3 的位置。攝影機仍然指向地圖的中心點,但現在可以看到位置 4 的線條所代表的區域。
在此螢幕截圖中,地圖的中心點仍與原始地圖相同,但地圖頂端顯示了更多地圖項目。若您將視角調整至 45 度以上,攝影機和地圖位置之間的地圖項目看起來會較大,而地圖位置以外的地圖項目則看起來較小,因而產生 3D 效果。
Zoom
地圖比例取決於攝影機的縮放等級。縮放等級較大時,螢幕上會顯示較多細節;縮放等級較小時,則能在螢幕上顯示較大的範圍。 縮放等級為 0 時,地圖比例是整個世界的寬度約為 256 個點。
將縮放等級提升 1,螢幕上的世界寬度就會加倍。因此,縮放等級若為 N,世界的寬度就大約是 256 * 2N 點。舉例來說,縮放等級為 2 時,整個世界的寬度大約是 1024 個點。
縮放等級不需要是整數。地圖允許的縮放等級範圍取決於許多因素,包括目標、地圖類型和螢幕大小。範圍外的任何數字都會轉換為下一個最接近的有效值,可能是最小或最大縮放等級。以下清單列出各縮放等級大致可顯示的精細程度:
- 1:全世界
- 5:自然景觀/大陸
- 10:城市
- 15:街道
- 20:建築
設定相機的初始位置
使用 GMSCameraPosition
物件設定攝影機的初始位置,可讓您設定目標的經緯度,以及方位角度、傾斜度和縮放功能。
如要設定初始相機位置,請建立 GMSMapViewOptions
物件,並將 camera
屬性設為 GMSCameraPosition
。接著,將選項傳遞至 GMSMapView
便利建構函式。
Swift
let options = GMSMapViewOptions() options.camera = GMSCameraPosition.camera(withLatitude: -33.8683, longitude: 151.2086, zoom: 16) let mapView = GMSMapView(options:options)
Objective-C
GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.camera = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:16]; GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];
您也可以使用預設的 UIView
init 方法建立 GMSMapView
物件。在這種情況下,攝影機位置會從預設位置開始,並在建立後變更。
Swift
let options = GMSMapViewOptions() options.frame = self.view.bounds let mapView = GMSMapView(options:options)
Objective-C
GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.frame = self.view.bounds; GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];
變更攝影機位置
你可以透過程式輔助方式變更攝影機位置,設定位置、方位角度、傾斜度和縮放功能。雖然 GMSMapView
提供多種可用於變更攝影機位置的方法,但您通常會使用 GMSCameraPosition
或 GMSCameraUpdate
:
GMSCameraPosition
包含用來變更每個攝影機位置參數的屬性和方法,例如目標、方位角度、傾斜度和縮放。GMSCameraUpdate
可讓您變更目標、方位、傾斜和縮放功能,還包含其他便利的方法,可支援捲動、進階縮放、將攝影機置於預先定義的邊界內等。
移動攝影機時,您可以選擇將攝影機「貼齊」至新位置,即沒有動畫或移動動畫。舉例來說,如果您以動畫方式呈現攝影機的目標位置變更,動畫就會從先前的位置平移到新的位置。
動畫會插入在目前攝影機屬性和新攝影機屬性之間。您可以使用核心動畫控制動畫的持續時間。
使用 GMSCameraPosition
如要使用 GMSCameraPosition
變更相機,請建立新物件或複製現有物件,然後在 GMSMapView
物件上設定該物件。使用 GMSCameraPosition
物件,將攝影機對齊到新位置 (無論是否加入動畫)。
使用 GMSCameraPosition
物件設定任何相機屬性,例如緯度、經度、縮放、航向和視角。然後,您可以使用該物件設定 GMSMapView
的 camera
屬性。
Swift
let fancy = GMSCameraPosition( latitude: -33, longitude: 151, zoom: 6, bearing: 270, viewingAngle: 45 ) mapView.camera = fancy
Objective-C
GMSCameraPosition *fancy = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:6 bearing:30 viewingAngle:45]; [mapView setCamera:fancy];
請省略任何您要設為預設值的 GMSCameraPosition
屬性。
如要為移動動作加上動畫效果,請使用 animateToCameraPosition:
方法,而不要設定 camera
屬性。
使用 GMSCameraUpdate
GMSCameraUpdate
可讓您更新攝影機位置,並選擇是否要跟新位置對齊或動畫。GMSCameraUpdate
的優勢在於便利。您可以使用 GMSCameraPosition
執行與 GMSCameraUpdate
相同的工作,但 GMSCameraUpdate
提供了其他輔助方法,可讓您更輕鬆地操作相機。
舉例來說,如要使用 GMSCameraPosition
增加目前的縮放等級,您必須先決定目前的縮放等級,然後建立 GMSCameraPosition
物件,將縮放等級設為大於目前縮放等級的值。
或者,您也可以使用 zoomIn:
方法建構 GMSCameraUpdate
物件。接著,將 GMSCameraUpdate
物件傳遞至 GMSMapView
animateWithCameraUpdate:
方法,即可更新相機。
Swift
// Zoom in one zoom level let zoomCamera = GMSCameraUpdate.zoomIn() mapView.animate(with: zoomCamera)
Objective-C
// Zoom in one zoom level GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn]; [mapView animateWithCameraUpdate:zoomCamera];
改用 GMSMapView
moveCamera:
方法將攝影機對齊新位置。
在下例中,您將使用 GMSCameraUpdate
為攝影機移動動作加入動畫,讓攝影機置於溫哥華。
Swift
// Center the camera on Vancouver, Canada let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11) let vancouverCam = GMSCameraUpdate.setTarget(vancouver) mapView.animate(with: vancouverCam)
Objective-C
// Center the camera on Vancouver, Canada CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11); GMSCameraUpdate *vancouverCam = [GMSCameraUpdate setTarget:vancouver]; [mapView animateWithCameraUpdate:vancouverCam];
建構 GMSCameraUpdate
物件
使用其中一種方法建構 GMSCameraUpdate
物件。
zoomIn:
和zoomOut:
- 以 1.0 為單位改變目前的縮放等級,其他所有屬性則保持不變。
zoomTo:
- 將縮放等級變更為指定值,所有其他屬性則保持不變。
zoomBy:
- 依照指定值增加 (或減少,如果值為負數) 縮放等級。
zoomBy:atPoint:
- 以指定值增加 (或減少時) 縮放等級,同時保留畫面上的指定點位置。
setTarget:
- 變更攝影機的經緯度,同時保留所有其他屬性。
setTarget:zoom:
- 變更攝影機的緯度、經度和縮放,同時保留所有其他屬性。
setCamera:
- 設定新的
GMSCameraPosition
。 scrollByX:Y:
- 變更攝影機的經緯度,以根據指定點數移動地圖。正的 x 值會使攝影機向右移動,因此地圖看起來會向左移。正的 y 值會使攝影機向下移動,因此地圖看起來會向上移。捲動的方向是相對於攝影機目前的航向。舉例來說,如果攝影機的航向為 90 度,「上方」就是東方。
fitBounds:
- 轉換相機,將螢幕上的指定邊界以最大可能的縮放等級置中。對 64 個點的邊界套用預設的邊框間距。
fitBounds:withPadding:
- 轉換相機,將螢幕上的指定邊界以最大可能的縮放等級置中。使用這個方法即可為定界框的所有邊指定相同的邊框間距 (以點為單位)。
fitBounds:withEdgeInsets:
- 轉換相機,將螢幕上的指定邊界以最大可能的縮放等級置中。使用
UIEdgeInsets
即可單獨指定定界框每一側的邊框間距。
使用 GMSMapView
變更單一屬性
GMSMapView
提供幾種方法,可讓您在不使用 GMSCameraPosition
物件或 GMSCameraUpdate
物件的情況下移動攝影機。使用這些方法 (例如 animateToLocation:
或 animateToZoom:
) 時,您可以為單一相機屬性的變更建立動畫。
舉例來說,使用 toViewingAngle:
方法即可為攝影機傾斜變更建立動畫效果。
Swift
mapView.animate(toViewingAngle: 45)
Objective-C
[mapView animateToViewingAngle:45];
設定目標 (位置)
位置會決定地圖的中心。位置是由經緯度指定,並由 CLLocationCoordinate2D
以程式輔助方式表示,使用 CLLocationCoordinate2DMake
建立。
使用 GMSCameraPosition
變更位置。在本例中,地圖會對齊新的位置。
Swift
let target = CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208) mapView.camera = GMSCameraPosition(target: target, zoom: 6)
Objective-C
CLLocationCoordinate2D target = CLLocationCoordinate2DMake(-33.868, 151.208); mapView.camera = [GMSCameraPosition cameraWithTarget:target zoom:6];
如要為變更加上動畫效果並平移地圖至新位置,可以使用 animateToCameraPosition:
方法,而不必設定 camera
屬性。或者,對 GMSMapView
使用 animateToLocation:
方法。
Swift
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208))
Objective-C
[mapView animateToLocation:CLLocationCoordinate2DMake(-33.868, 151.208)];
你也可以建立 GMSCameraUpdate
物件來移動攝影機。請使用內建的方法 scrollByX:Y:
,指定以 X 和 Y 方向捲動相機的點數。在這個範例中,您將攝影機向右捲動 200 點,向下捲動 100 點:
Swift
// Move the camera 200 points to the right, and 100 points downwards let downwards = GMSCameraUpdate.scrollBy(x: 200, y: 100) mapView.animate(with: downwards)
Objective-C
// Move the camera 200 points to the right, and 100 points downwards GMSCameraUpdate *downwards = [GMSCameraUpdate scrollByX:200.0 Y:100.0]; [mapView animateWithCameraUpdate:downwards];
設定航向 (方向)
航向是指指南針方向,以度為單位,從正北算起,測量地圖頂端邊緣。舉例來說,90 度的航向會使地圖頂部的邊緣指向東方。
您可以使用 GMSCameraPosition
、GMSCameraUpdate
或 GMSMapView
的 animateToBearing:
方法,透過程式輔助方式設定航向。
Swift
mapView.animate(toBearing: 0)
Objective-C
[mapView animateToBearing:0];
設定傾斜角度 (視角)
視角是指攝影機在地圖中心位置正上方與地球表面之間的弧線位置,從天底 (攝影機正下方) 算起,以度為單位測量。視角改變時,地圖會以視角顯示,攝影機和地圖位置之間的地圖項目看起來會較大,而地圖位置以外的地圖項目則相對較小,因而產生 3D 效果。
視角範圍介於 0 之間 (直線在地圖上正下方),最多可達縮放等級依上限而定。如果是縮放等級 16 以上,最大角度為 65 度。縮放等級為 10 或以下時,最大角度為 30 度。
使用 GMSCameraPosition
、GMSCameraUpdate
或 GMSMapView
的 animateToViewingAngle:
方法,透過程式輔助方式設定視角。
Swift
mapView.animate(toViewingAngle: 45)
Objective-C
[mapView animateToViewingAngle:45];
設定縮放比例
地圖比例取決於攝影機的縮放等級。縮放等級較大時,螢幕上會顯示較多細節;縮放等級較小時,則可看得更完整。
您可以使用 GMSCameraPosition
、GMSCameraUpdate
或 GMSMapView
的 animateToZoom:
方法,以程式輔助方式設定縮放比例。
Swift
mapView.animate(toZoom: 12)
Objective-C
[mapView animateToZoom:12];
以下範例使用 zoomIn:
方法建構 GMSCameraUpdate
物件,以動畫呈現目前等級的某個等級放大畫面。
Swift
// Zoom in one zoom level let zoomCamera = GMSCameraUpdate.zoomIn() mapView.animate(with: zoomCamera)
Objective-C
// Zoom in one zoom level GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn]; [mapView animateWithCameraUpdate:zoomCamera];
設定條件範圍
如要移動攝影機,以最大可能的縮放等級顯示整個感興趣的區域,請設定攝影機檢視畫面的邊界。舉例來說,如果您要顯示使用者目前位置周圍五英里內的所有加油站,請移動攝影機讓所有加油站都顯示在螢幕上:
- 計算您想要在畫面上顯示的
GMSCoordinateBounds
。 - 使用
GMSMapView
的cameraForBounds:insets:
方法傳回新的GMSCameraPosition
。
設定這些邊界可確保指定的 GMSCoordinateBounds
完全符合目前地圖的尺寸。請注意,這個方法會將地圖的傾斜和航向設為 0。
以下範例說明如何更改攝影機,讓溫哥華和卡加利的城市出現在相同的檢視畫面中。
Swift
let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11) let calgary = CLLocationCoordinate2D(latitude: 51.05,longitude: -114.05) let bounds = GMSCoordinateBounds(coordinate: vancouver, coordinate: calgary) let camera = mapView.camera(for: bounds, insets: UIEdgeInsets())! mapView.camera = camera
Objective-C
CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11); CLLocationCoordinate2D calgary = CLLocationCoordinate2DMake(51.05, -114.05); GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:vancouver coordinate:calgary]; GMSCameraPosition *camera = [mapView cameraForBounds:bounds insets:UIEdgeInsetsZero]; mapView.camera = camera;
限制使用者只能在特定區域內平移
這些情境會設定地圖的邊界,但使用者可以捲動或平移至這些邊界之外。因此,建議您限制地圖焦點 (攝影機目標) 的座標中心邊界,讓使用者只能在這些邊界內捲動和平移。
舉例來說,購物中心或機場的零售應用程式可以將地圖限制在特定範圍內,讓使用者在這些範圍內捲動及平移。
如要將平移範圍限制在特定邊界,請將 GMSMapView
的 cameraTargetBounds
屬性設為 GMSCoordinateBounds
物件,以便定義所需邊界。如要稍後移除限制,請將 cameraTargetBounds
設為 nil。
Swift
mapView.cameraTargetBounds = bounds
Objective-C
mapView.cameraTargetBounds = bounds;
下圖說明將攝影機目標限制在比可視區域稍大範圍的情況。只要攝影機目標仍在限制區域內,使用者就能捲動及平移地圖。交叉符號代表攝影機目標:
即使可視區域會顯示超出定義邊界的區域,地圖仍會將可視區域填滿。舉例來說,如果您將攝影機目標放在限制區域的角落,可視區域中就會出現該角落以外的區域,但使用者無法捲動至該區域。請參考下圖說明。交叉符號代表攝影機目標:
在下圖中,攝影機目標的範圍非常有限,因此使用者幾乎無法捲動或平移地圖。交叉符號代表攝影機目標:
設定最小或最大變焦
全域常數 kGMSMinZoomLevel
和 kGMSMaxZoomLevel
會定義縮放等級的最小或最大值。根據預設,GMSMapView
的 minZoom
和 maxZoom
屬性會設為這些常數。
如要限制地圖可以使用的縮放等級範圍,請設定最小和最大縮放等級。下方程式碼將縮放等級限制在 10 和 15 之間。
Swift
let camera = GMSCameraPosition( latitude: 41.887, longitude: -87.622, zoom: 12 ) let mapView = GMSMapView(frame: .zero, camera: camera) mapView.setMinZoom(10, maxZoom: 15)
Objective-C
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:41.887 longitude:-87.622 zoom:12]; GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; [mapView setMinZoom:10 maxZoom:15];
您必須使用 setMinZoom:maxZoom:
方法設定縮放範圍,但您可以使用 minZoom
和 maxZoom
屬性讀取目前的值。僅限制其中一個值時,這種方法很有用。下列程式碼僅變更最小縮放等級。
Swift
mapView.setMinZoom(12, maxZoom: mapView.maxZoom)
Objective-C
[mapView setMinZoom:12 maxZoom:mapView.maxZoom];
更新最小和最大縮放等級後,如果相機的縮放等級設為新範圍外的值,目前縮放會自動更新,以顯示最接近的有效值。舉例來說,在下列程式碼中,原始變焦定義為 4。當變焦範圍之後設為 10 到 15 時,目前的縮放比例會更新為 10。
Swift
// Sets the zoom level to 4. let camera2 = GMSCameraPosition( latitude: 41.887, longitude: -87.622, zoom: 4 ) let mapView2 = GMSMapView(frame: .zero, camera: camera) // The current zoom, 4, is outside of the range. The zoom will change to 10. mapView.setMinZoom(10, maxZoom: 15)
Objective-C
// Sets the zoom level to 4. GMSCameraPosition *camera2 = [GMSCameraPosition cameraWithLatitude:41.887 longitude:-87.622 zoom:4]; GMSMapView *mapView2 = [GMSMapView mapWithFrame:CGRectZero camera:camera]; // The current zoom, 4, is outside of the range. The zoom will change to 10. [mapView setMinZoom:10 maxZoom:15];