1. Başlamadan önce
Bu codelab'de, iOS için Haritalar 3D SDK'sını kullanarak SwiftUI'de 3D harita uygulaması oluşturmayı öğreneceksiniz.
Öğrenecekleriniz:
- Kamerayı kontrol ederek konumları görüntüleyebilir ve harita üzerinde uçabilirsiniz.
- İşaretçi ve model ekleme
- Çizgi ve poligon çizme
- Kullanıcıların yer işaretçilerini tıklamasını işleme
Ön koşullar
- Faturalandırmanın etkin olduğu bir Google Console projesi
- İsteğe bağlı olarak iOS için Haritalar 3D SDK'sıyla kısıtlanmış bir API anahtarı.
- SwiftUI ile iOS geliştirme hakkında temel düzeyde bilgi
Yapacaklarınız
- Xcode'u ayarlama ve Swift Package Manager'ı kullanarak SDK'yı getirme
- Uygulamanızı API anahtarı kullanacak şekilde yapılandırma
- Uygulamanıza temel bir 3D harita ekleme
- Belirli konumlara uçmak ve bu konumların etrafında uçmak için kamerayı kontrol etme
- Haritanıza işaretçi, çizgi, poligon ve model ekleme
İhtiyacınız olanlar
- Xcode 15 veya sonraki bir sürüm.
2. Hazırlanın
Aşağıdaki etkinleştirme adımı için iOS için Haritalar 3D SDK'sını etkinleştirmeniz gerekir.
Google Haritalar Platformu'nu ayarlama
Google Cloud Platform hesabınız ve faturalandırmanın etkin olduğu bir projeniz yoksa faturalandırma hesabı ve proje oluşturmak için lütfen Google Haritalar Platformu'nu kullanmaya başlama kılavuzunu inceleyin.
- Cloud Console'da proje açılır menüsünü tıklayın ve bu kod laboratuvarını kullanmak istediğiniz projeyi seçin.
- Google Cloud Marketplace'te bu kod laboratuvarı için gereken Google Haritalar Platformu API'lerini ve SDK'larını etkinleştirin. Bunun için bu videodaki veya bu dokümanlardaki adımları uygulayın.
- Cloud Console'un Kimlik Bilgileri sayfasında bir API anahtarı oluşturun. Bu videodaki veya bu dokümanlardaki adımları uygulayabilirsiniz. Google Haritalar Platformu'na yapılan tüm istekler için API anahtarı gerekir.
iOS için Haritalar 3D SDK'sını etkinleştirme
iOS için Haritalar 3D SDK'sını, konsoldaki Google Haritalar Platformu > API'ler ve Hizmetler menü bağlantısını kullanarak bulabilirsiniz.
Seçtiğiniz projede API'yi etkinleştirmek için Etkinleştir'i tıklayın.
3. Temel bir SwiftUI uygulaması oluşturma
Not: Her bir adıma ait çözüm kodunu GitHub'daki codelab örnek uygulama deposunda bulabilirsiniz .
Xcode'da yeni bir uygulama oluşturun.
Bu adımın kodunu GitHub'daki GoogleMaps3DDemo klasöründe bulabilirsiniz.
Xcode'u açıp yeni bir uygulama oluşturun. SwiftUI'yi belirtin.
Uygulamanızı GoogleMaps3DDemo
olarak adlandırın ve com.example.GoogleMaps3DDemo
paket adını kullanın.
GoogleMaps3D kitaplığını projenize aktarma
Swift Package Manager'ı kullanarak SDK'yı projenize ekleyin.
Xcode projenizde veya çalışma alanınızda Dosya > Paket Bağımlılıkları Ekle'ye gidin. URL olarak https://github.com/googlemaps/ios-maps-3d-sdk adresini girin, paketi almak için Enter tuşuna basın ve "Paket Ekle"yi tıklayın.
Paket Ürünlerini Seçin penceresinde, GoogleMaps3D
'ün, belirttiğiniz ana hedefinize ekleneceğini doğrulayın. Bu işlem tamamlandıktan sonra Paket Ekle'yi tıklayın.
Yüklemenizin doğru olup olmadığını kontrol etmek için hedefinizin Genel bölmesine gidin. Çerçeveler, Kitaplıklar ve Yerleşik İçerik bölümünde yüklü paketleri görürsünüz. Paketi ve sürümünü doğrulamak için Proje Gezgini'nin Paket Bağımlılıkları bölümünü de görüntüleyebilirsiniz.
API anahtarınızı ekleme
API anahtarınızı uygulamaya sabit kod olarak ekleyebilirsiniz ancak bu iyi bir uygulama değildir. Yapılandırma dosyası eklemek, API anahtarınızı gizli tutmanıza olanak tanır ve kaynak denetimine eklenmesini önler.
Proje kök klasöründe yeni bir yapılandırma dosyası oluşturun
Xcode'da proje gezgini penceresini görüntülediğinizden emin olun. Proje kökünü sağ tıklayın ve "Şablondan Yeni Dosya"yı seçin. "Yapılandırma Ayarları Dosyası"nı görene kadar aşağı kaydırın. Bunu seçip "Sonraki"yi tıklayın. Dosyayı Config.xcconfig
olarak adlandırın ve proje kök klasörünün seçildiğinden emin olun. Dosyayı oluşturmak için "Oluştur"u tıklayın.
Düzenleyicide, yapılandırma dosyasına aşağıdaki gibi bir satır ekleyin: MAPS_API_KEY = YOUR_API_KEY
YOUR_API_KEY
yerine API anahtarınızı girin.
Bu ayarı Info.plist
'e ekleyin.
Bunu yapmak için proje kökünü seçin ve "Bilgi" sekmesini tıklayın.
$(MAPS_API_KEY)
değerine sahip MAPS_API_KEY
adlı yeni bir mülk ekleyin.
Örnek uygulama kodunda bu özelliği belirten bir Info.plist
dosyası vardır.
Harita ekleme
GoogleMaps3DDemoApp.swift
adlı dosyayı açın. Bu, uygulamanızın giriş noktası ve ana gezinme menüsüdür.
Merhaba Dünya mesajı gösteren ContentView()
işlevini çağırır.
ContentView.swift
dosyasını düzenleyicide açın.
GoogleMaps3D
için bir import
ifadesi ekleyin.
var body: some View {}
kod bloğundaki kodu silin. body
içinde yeni bir Map()
tanımlayın.
Bir Map
'ü başlatmak için gereken minimum yapılandırma bir MapMode
'tur. Bu özelliğin iki olası değeri vardır:
.hybrid
: Yollar ve etiketler içeren uydu görüntüleri veya.satellite
: Yalnızca uydu görüntüleri.
.hybrid
Farkını Tercih Edin.
ContentView.swift
dosyanız aşağıdaki gibi görünmelidir.
import GoogleMaps3D
import SwiftUI
@main
struct ContentView: View {
var body: some View {
Map(mode: .hybrid)
}
}
API anahtarınızı ayarlayın.
API anahtarı, harita başlatılmadan önce ayarlanmalıdır.
Bunu, harita içeren herhangi bir View
öğesinin init()
olay işleyicisinde Map.apiKey
ayarlayarak yapabilirsiniz. Ayrıca ContentView()
'u aramadan önce GoogleMaps3DDemoApp.swift
'te de ayarlayabilirsiniz.
GoogleMaps3DDemoApp.swift
içinde, WindowGroup
öğesinin onAppear
etkinlik işleyicisinde Map.apiKey
değerini ayarlayın.
API anahtarınızı yapılandırma dosyasından getirme
Yapılandırma dosyanızda oluşturduğunuz MAPS_API_KEY
ayarına erişmek için Bundle.main.infoDictionary
kullanın.
import GoogleMaps3D
import SwiftUI
@main
struct GoogleMaps3DDemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.onAppear {
guard let infoDictionary: [String: Any] = Bundle.main.infoDictionary else {
fatalError("Info.plist not found")
}
guard let apiKey: String = infoDictionary["MAPS_API_KEY"] as? String else {
fatalError("MAPS_API_KEY not set in Info.plist")
}
Map.apiKey = apiKey
}
}
}
Doğru şekilde yüklenip yüklenmediğini kontrol etmek için uygulamanızı derleyip çalıştırın. Dünya haritasını görürsünüz.
4. Harita görünümünü kontrol etmek için kamerayı kullanma
Kamera durumu nesnesi oluşturma
3D harita görünümleri Camera
sınıfı tarafından kontrol edilir. Bu adımda, harita görünümünü özelleştirmek için konumu, irtifayı, yönü, eğimi, yuvarlanmayı ve menzili belirtmeyi öğreneceksiniz.
Kamera ayarlarını depolamak için bir Yardımcılar sınıfı oluşturma
MapHelpers.swift
adlı yeni bir boş dosya ekleyin. Yeni dosyanızda GoogleMaps3D
dosyasını içe aktarın ve Camera
sınıfına bir uzantı ekleyin. sanFrancisco
adlı bir değişken ekleyin. Bu değişkeni yeni bir Camera
nesnesi olarak başlatın. Kamerayı latitude: 37.39, longitude: -122.08
konumunda bulun.
import GoogleMaps3D
extension Camera {
public static var sanFrancisco: Camera = .init(latitude: 37.39, longitude: -122.08)
}
Uygulamanıza yeni bir görünüm ekleme
CameraDemo.swift
adlı yeni bir dosya oluşturun. Dosyaya yeni bir SwiftUI Görünümü'nün temel ana hatlarını ekleyin.
Camera
türüne sahip camera
adlı bir @State
değişkeni ekleyin. Yeni tanımladığınız sanFrancisco
kamerayla başlatın.
@State
kullanarak haritayı kamera durumuna bağlayabilir ve doğru bilgi kaynağı olarak kullanabilirsiniz.
@State var camera: Camera = .sanFrancisco
Map()
işlev çağrısını, camera
özelliğini içerecek şekilde değiştirin. camera
mülkünü kamera @State
nesnenizde (.sanFrancisco
) başlatmak için kamera durumu bağlama $camera
özelliğini kullanın.
import SwiftUI
import GoogleMaps3D
struct CameraDemo: View {
@State var camera: Camera = .sanFrancisco
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid)
}
}
}
Uygulamanıza temel gezinme kullanıcı arayüzü ekleme
Ana uygulama giriş noktasına (GoogleMaps3DDemoApp.swift
) bir NavigationView
ekleyin.
Bu sayede kullanıcılar demoların listesini görebilir ve her birini tıklayarak açabilir.
Yeni bir NavigationView
eklemek için GoogleMaps3DDemoApp.swift
'yi düzenleyin.
İki NavigationLink
beyanı içeren bir List
ekleyin.
İlk NavigationLink
, ContentView()
'u Text
açıklamasıyla Basic Map
açmalıdır.
İkinci NavigationLink
, CameraDemo()
'u açar.
...
NavigationView {
List {
NavigationLink(destination: ContentView()) {
Text("Basic Map")
}
NavigationLink(destination: CameraDemo()) {
Text("Camera Demo")
}
}
}
...
Xcode önizlemesi ekleme
Önizlemeler, uygulamanızda değişiklik yaparken uygulamanızı görmenize ve uygulamanızla etkileşime geçmenize olanak tanıyan güçlü bir Xcode özelliğidir.
Önizleme eklemek için CameraDemo.swift
'ü açın. struct
dışında bir #Preview {}
kod bloğu ekleyin.
#Preview {
CameraDemo()
}
Xcode'da Önizleme bölmesini açın veya yenileyin. Haritada San Francisco gösterilmelidir.
Özel 3D görünümler oluşturma
Kamerayı kontrol etmek için ek parametreler belirtebilirsiniz:
heading
: Kameranın kuzeyden hangi yöne bakacağını derece cinsinden gösteren yön.tilt
: Eğilme açısının derece cinsinden değeri. 0 doğrudan başınızın üzerinde, 90 ise yatay olarak baktığınız anlamına gelir.roll
: Kameranın dikey düzlemi etrafında derece cinsinden yan yatma açısırange
: Kameranın enlem, boylam konumuna olan mesafesi (metre cinsinden)altitude
: Kameranın deniz seviyesinden yüksekliği
Bu ek parametrelerden hiçbirini sağlamazsanız varsayılan değerler kullanılır.
Kamera görünümünde daha fazla 3D veri gösterilmesi için ilk parametreleri daha yakın ve eğik bir görünüm gösterecek şekilde ayarlayın.
MapHelpers.swift
içinde tanımladığınız Camera
öğesini altitude
, heading
, tilt
, roll
ve range
değerlerini içerecek şekilde düzenleyin
public static var sanFrancisco: Camera = .init(
latitude: 37.7845812,
longitude: -122.3660241,
altitude: 585,
heading: 288.0,
tilt: 75.0,
roll: 0.0,
range: 100)
Yeni 3D görünümü görmek ve keşfetmek için uygulamayı derleyip çalıştırın.
5. Temel kamera animasyonları
Şimdiye kadar kamerayı kullanarak eğim, yükseklik, yön ve menzil içeren tek bir konum belirttiniz. Bu adımda, bu mülkleri ilk durumdan yeni bir duruma animasyonlu olarak taşıyarak kamera görüntüsünü nasıl taşıyacağınızı öğreneceksiniz.
Bir yere uçma
Kamerayı ilk konumdan yeni bir konuma animasyonlu olarak taşımak için Map.flyCameraTo()
yöntemini kullanacaksınız.
flyCameraTo()
yöntemi birkaç parametre alır:
- Bitiş konumunu temsil eden bir
Camera
. duration
: Animasyonun saniye cinsinden süresi.trigger
: Durumu değiştiğinde animasyonu tetikleyecek gözlemlenebilir bir nesne.completion
: Animasyon tamamlandığında yürütülecek kod.
Uçuş yapılacak bir konum tanımlama
MapHelpers.swift
dosyanızı açın.
Seattle'ı göstermek için yeni bir kamera nesnesi tanımlayın.
public static var seattle: Camera = .init(latitude:
47.6210296,longitude: -122.3496903, heading: 149.0, tilt: 77.0, roll: 0.0, range: 4000)
Animasyonu tetikleyecek bir düğme ekleyin.
CameraDemo.swift
cihazınızı açın. struct
içinde yeni bir Boole değişkeni tanımlayın.
animate
olarak adlandırın ve ilk değeri false
olarak ayarlayın.
@State private var animate: Bool = false
VStack
altına bir Button
ekleyin. Button
, harita animasyonunu başlatır.
Button
için "Uçmaya Başla" gibi uygun bir Text
girin.
import SwiftUI
import GoogleMaps3D
struct CameraDemo: View {
@State var camera:Camera = .sanFrancisco
@State private var animate: Bool = false
var body: some View {
VStack{
Map(camera: $camera, mode: .hybrid)
Button("Start Flying") {
}
}
}
}
Düğme kapatma bölümünde, animate
değişkeninin durumunu değiştirecek kod ekleyin.
Button("Start Flying") {
animate.toggle()
}
Animasyonu başlatın.
animate
değişkeninin durumu değiştiğinde flyCameraTo()
animasyonunu tetikleyecek kodu ekleyin.
var body: some View {
VStack{
Map(camera: $camera, mode: .hybrid)
.flyCameraTo(
.seattle,
duration: 5,
trigger: animate,
completion: { }
)
Button("Start Flying") {
animate.toggle()
}
}
}
Bir konumun etrafında uçma
Bir konumun etrafında uçmak için Map.flyCameraAround()
yöntemi kullanılabilir. Bu yöntem birkaç parametre alır:
- konumu ve görünümü tanımlayan bir
Camera
. duration
saniye içinde.rounds
: Animasyonun tekrar sayısı.trigger
: Animasyonu tetikleyecek gözlemlenebilir bir nesne.callback
: Animasyon çalıştırıldığında çalışacak kod.
flyAround
adlı, ilk değeri false
olan yeni bir @State
değişkeni tanımlayın.
Bunu yaptıktan sonra, flyCameraTo()
yöntem çağrısından hemen sonra flyCameraAround()
çağrısı ekleyin.
Görünümün sorunsuz bir şekilde değişebilmesi için çevreyi uçuş süresi nispeten uzun olmalıdır.
flyCameraTo()
tamamlandığında tetikleyici nesnenin durumunu değiştirerek flyCameraAround()
animasyonunu tetiklediğinizden emin olun.
Kodunuz aşağıdaki gibi görünmelidir.
import SwiftUI
import GoogleMaps3D
struct CameraDemo: View {
@State var camera:Camera = .sanFrancisco
@State private var animate: Bool = false
@State private var flyAround: Bool = false
var body: some View {
VStack{
Map(camera: $camera, mode: .hybrid)
.flyCameraTo(
.seattle,
duration: 5,
trigger: animate,
completion: { flyAround = true }
)
.flyCameraAround(
.seattle,
duration: 15,
rounds: 0.5,
trigger: flyAround,
callback: { }
)
Button("Start Flying") {
animate.toggle()
}
}
}
}
#Preview {
CameraDemo()
}
flyCameraTo()
animasyonu tamamlandıktan sonra kameranın hedefin etrafında uçtuğunu görmek için uygulamayı önizleyin veya çalıştırın.
6. Haritanıza bir işaretçi ekleyin.
Bu adımda, haritada nasıl işaretçi iğnesi çizeceğinizi öğreneceksiniz.
Bir Marker
nesnesi oluşturup haritanıza eklersiniz. SDK, işaretçi için varsayılan bir simge kullanır. Son olarak, işaretçiyi nasıl gösterileceğini değiştirmek için işaretçi rakımı ve diğer özellikleri ayarlarsınız.
İşaretçi denemeniz için yeni bir SwiftUI Görünümü oluşturun.
Projenize yeni bir Swift dosyası ekleyin. MarkerDemo.swift
olarak adlandırın.
Bir SwiftUI Görünümü'nün ana hatlarını ekleyin ve haritayı CameraDemo
'inizde yaptığınız gibi başlatın.
import SwiftUI
import GoogleMaps3D
struct MarkerDemo: View {
@State var camera: Camera = .sanFrancisco
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid)
}
}
}
Marker nesnesi başlatma
mapMarker
adlı yeni bir işaretçi değişkeni tanımlayın. MarkerDemo.swift
içindeki struct
kod bloğunun üst kısmında.
Tanımı, camera
beyanınızın altındaki satıra yerleştirin. Bu örnek kod, mevcut tüm mülkleri başlatır.
@State var mapMarker: Marker = .init(
position: .init(
latitude: 37.8044862,
longitude: -122.4301493,
altitude: 0.0),
altitudeMode: .absolute,
collisionBehavior: .required,
extruded: false,
drawsWhenOccluded: true,
sizePreserved: true,
zIndex: 0,
label: "Test"
)
İşaretçiyi haritanıza ekleyin.
İşaretçiyi çizmek için harita oluşturulduğunda çağrılan bir kapatıcıya ekleyin.
struct MarkerDemo: View {
@State var camera: Camera = .sanFrancisco
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid) {
mapMarker
}
}
}
}
GoogleMaps3DDemoApp.swift
alanına MarkerDemo()
hedefli ve Text
"İşaretçi Demo" olarak tanımlanan yeni bir NavigationLink
ekleyin.
...
NavigationView {
List {
NavigationLink(destination: Map()) {
Text("Basic Map")
}
NavigationLink(destination: CameraDemo()) {
Text("Camera Demo")
}
NavigationLink(destination: MarkerDemo()) {
Text("Marker Demo")
}
}
}
...
Uygulamanızı önizleme ve çalıştırma
İşaretçiyi görmek için önizlemeyi yenileyin veya uygulamanızı çalıştırın.
Ekstrüde İşaretçiler
İşaretler, altitude
ve altitudeMode
kullanılarak zeminin veya 3D örgünün üzerine yerleştirilebilir.
MarkerDemo.swift
içindeki mapMarker
bildirimini extrudedMarker
adlı yeni bir Marker
değişkenine kopyalayın.
altitude
için sıfır olmayan bir değer ayarlayın. 50 yeterlidir.
altitudeMode
değerini .relativeToMesh
olarak değiştirin ve extruded
değerini true
olarak ayarlayın. İşaretçiyi bir gökdelenin üzerine yerleştirmek için buradaki kod snippet'indeki latitude
ve longitude
değerlerini kullanın.
@State var extrudedMarker: Marker = .init(
position: .init(
latitude: 37.78980534,
longitude: -122.3969349,
altitude: 50.0),
altitudeMode: .relativeToMesh,
collisionBehavior: .required,
extruded: true,
drawsWhenOccluded: true,
sizePreserved: true,
zIndex: 0,
label: "Extruded"
)
Uygulamayı tekrar çalıştırın veya önizleyin. İşaretçi, 3D bir binanın üzerinde görünür.
7. Haritanıza bir model ekleyin.
Model
, Marker
ile aynı şekilde eklenebilir. URL ile erişilebilen veya projenize yerel dosya olarak eklenebilen bir model dosyasına ihtiyacınız vardır. Bu adımda, bu kod laboratuvarının GitHub deposundan indirebileceğiniz yerel bir dosya kullanacağız.
Projenize model dosyası ekleme
Xcode projenizde Models
adlı yeni bir klasör oluşturun.
GitHub örnek uygulama deposundan modeli indirin. Xcode proje görünümündeki yeni klasöre sürükleyerek projenize ekleyin.
Hedefi, uygulamanızın ana hedefi olacak şekilde ayarladığınızdan emin olun.
Projenizin Derleme Aşamaları > Paket Kaynaklarını Kopyala ayarlarını kontrol edin. Model dosyası, pakete kopyalanan kaynaklar listesinde olmalıdır. Orada değilse eklemek için "+" simgesini tıklayın.
Modeli uygulamanıza ekleyin.
ModelDemo.swift
adlı yeni bir SwiftUI dosyası oluşturun.
Önceki adımlarda olduğu gibi SwiftUI
ve GoogleMaps3D
için import
ifadeleri ekleyin.
body
dosyanızda VStack
içinde bir Map
tanımlayın.
import SwiftUI
import GoogleMaps3D
struct ModelDemo: View {
@State var camera: Camera = .sanFrancisco
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid) {
}
}
}
}
Paketinizden model yolunu alın. Bunun kodunu struct
dışından ekleyin.
private let fileUrl = Bundle.main.url(forResource: "balloon", withExtension: "glb")
Yapı içinde modeliniz için bir değişken tanımlayın.
fileUrl
sağlanmadığında varsayılan bir değer girin.
@State var balloonModel: Model = .init(
position: .init(
latitude: 37.791376,
longitude: -122.397571,
altitude: 300.0),
url: URL(fileURLWithPath: fileUrl?.relativePath ?? ""),
altitudeMode: .absolute,
scale: .init(x: 5, y: 5, z: 5),
orientation: .init(heading: 0, tilt: 0, roll: 0)
)
3. Modeli haritanızla kullanın.
Marker
eklerken olduğu gibi, Map
beyanında Model
'unuzun referansını sağlamanız yeterlidir.
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid) {
balloonModel
}
}
}
Uygulamanızı önizleme ve çalıştırma
GoogleMaps3DDemoApp.swift
alanına, hedefi ModelDemo()
ve Text
"Model Demo" olan yeni bir NavigationLink
ekleyin.
...
NavigationLink(destination: ModelDemo()) {
Text("Model Demo")
}
...
Modeli görmek için önizlemeyi yenileyin veya uygulamanızı çalıştırın.
8. Haritanızda bir çizgi ve poligon çizin.
Bu adımda, 3D haritanıza nasıl çizgi ve poligon şekli ekleyeceğinizi öğreneceksiniz.
Basitlik açısından şekilleri LatLngAltitude
nesneleri dizileri olarak tanımlayacaksınız. Gerçek bir uygulamada veriler bir dosyadan, API çağrısından veya veritabanından yüklenebilir.
Şekil verilerini yönetmek için bazı şekil nesneleri oluşturun.
MapHelpers.swift
alanına, San Francisco şehir merkezini kapsayan yeni bir Camera
tanımı ekleyin.
public static var downtownSanFrancisco: Camera = .init(latitude: 37.7905, longitude: -122.3989, heading: 25, tilt: 71, range: 2500)
Projenize ShapesDemo.swift
adlı yeni bir dosya ekleyin. View
protokolünü uygulayan ShapesDemo
adlı bir struct
ekleyin ve buna bir body
ekleyin.
struct ShapesDemo: View {
@State var camera: Camera = .downtownSanFrancisco
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid) {
}
}
}
}
Şekil verilerini yönetmek için kullanacağınız sınıflar Polyline
ve Polygon
'dır. ShapesDemo.swift
'ü açın ve aşağıdaki gibi struct
'a ekleyin.
var polyline: Polyline = .init(coordinates: [
LatLngAltitude(latitude: 37.80515638571346, longitude: -122.4032569467164, altitude: 0),
LatLngAltitude(latitude: 37.80337073509504, longitude: -122.4012878349353, altitude: 0),
LatLngAltitude(latitude: 37.79925208843463, longitude: -122.3976697250461, altitude: 0),
LatLngAltitude(latitude: 37.7989102378512, longitude: -122.3983408725656, altitude: 0),
LatLngAltitude(latitude: 37.79887832784348, longitude: -122.3987094864192, altitude: 0),
LatLngAltitude(latitude: 37.79786443410338, longitude: -122.4066878788802, altitude: 0),
LatLngAltitude(latitude: 37.79549248916587, longitude: -122.4032992702785, altitude: 0),
LatLngAltitude(latitude: 37.78861484290265, longitude: -122.4019489189814, altitude: 0),
LatLngAltitude(latitude: 37.78618687561075, longitude: -122.398969592545, altitude: 0),
LatLngAltitude(latitude: 37.7892310309145, longitude: -122.3951458683092, altitude: 0),
LatLngAltitude(latitude: 37.7916358762409, longitude: -122.3981969390652, altitude: 0)
])
.stroke(GoogleMaps3D.Polyline.StrokeStyle(
strokeColor: UIColor(red: 0.09803921568627451, green: 0.403921568627451, blue: 0.8235294117647058, alpha: 1),
strokeWidth: 10.0,
outerColor: .white,
outerWidth: 0.2
))
.contour(GoogleMaps3D.Polyline.ContourStyle(isGeodesic: true))
var originPolygon: Polygon = .init(outerCoordinates: [
LatLngAltitude(latitude: 37.79165766856578, longitude: -122.3983762901255, altitude: 300),
LatLngAltitude(latitude: 37.7915324439261, longitude: -122.3982171091383, altitude: 300),
LatLngAltitude(latitude: 37.79166617650914, longitude: -122.3980478493319, altitude: 300),
LatLngAltitude(latitude: 37.79178986470217, longitude: -122.3982041104199, altitude: 300),
LatLngAltitude(latitude: 37.79165766856578, longitude: -122.3983762901255, altitude: 300 )
],
altitudeMode: .relativeToGround)
.style(GoogleMaps3D.Polygon.StyleOptions(fillColor:.green, extruded: true) )
var destinationPolygon: Polygon = .init(outerCoordinates: [
LatLngAltitude(latitude: 37.80515661739527, longitude: -122.4034307490334, altitude: 300),
LatLngAltitude(latitude: 37.80503794515428, longitude: -122.4032633416024, altitude: 300),
LatLngAltitude(latitude: 37.80517850164195, longitude: -122.4031056058006, altitude: 300),
LatLngAltitude(latitude: 37.80529346901115, longitude: -122.4032622466595, altitude: 300),
LatLngAltitude(latitude: 37.80515661739527, longitude: -122.4034307490334, altitude: 300 )
],
altitudeMode: .relativeToGround)
.style(GoogleMaps3D.Polygon.StyleOptions(fillColor:.red, extruded: true) )
Kullanılan ilk başlatma parametrelerine dikkat edin.
altitudeMode: .relativeToGround
, poligonları yerden belirli bir yüksekliğe çıkarmak için kullanılır.altitudeMode: .clampToGround
, çoklu çizginin dünyanın yüzeyinin şeklini takip etmesini sağlamak için kullanılır..init()
çağrıldıktan sonrastyleOptions()
için bir yöntem çağrısı zincirlenerekPolygon
nesnelerinde stiller ayarlanır
Şekilleri haritaya ekleme
Önceki adımlarda olduğu gibi, şekiller doğrudan Map
kapatma işlemine eklenebilir. Map
öğenizi bir VStack
içinde oluşturun.
...
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid) {
polyline
originPolygon
destinationPolygon
}
}
}
...
Uygulamanızı önizleme ve çalıştırma
Xcode'daki Önizleme bölmesine önizleme kodu ekleyin ve uygulamanızı inceleyin.
#Preview {
ShapesDemo()
}
Uygulamanızı çalıştırmak için GoogleMaps3DDemoApp.swift
'a yeni bir NavigationLink
ekleyin. Bu NavigationLink
, yeni demo görünümünü açar.
...
NavigationLink(destination: ShapesDemo()) {
Text("Shapes Demo")
}
...
Uygulamanızı çalıştırın ve eklediğiniz şekilleri keşfedin.
9. Yer işaretçilerinde dokunma etkinliklerini işleme
Bu adımda, kullanıcıların yer işaretlerine dokunmalarına nasıl yanıt vereceğinizi öğreneceksiniz.
Not: Yer işaretçilerini haritada görmek için MapMode
'ü .hybrid
olarak ayarlamanız gerekir.
Dokunmayı işlemek için Map.onPlaceTap
yönteminin uygulanması gerekir.
onPlaceTap
etkinliği, dokunulan yer işaretçisinin yer kimliğini alabileceğiniz bir PlaceTapInfo
nesnesi sağlar.
Yerler SDK'sı veya Yerler API'yi kullanarak daha fazla ayrıntıyı öğrenmek için yer kimliğini kullanabilirsiniz.
Yeni Swift Görünümü ekleme
Aşağıdaki kodu PlaceTapDemo.swift
adlı yeni bir Swift dosyasına ekleyin.
import GoogleMaps3D
import SwiftUI
struct PlaceTapDemo: View {
@State var camera: Camera = .sanFrancisco
@State var isPresented = false
@State var tapInfo: PlaceTapInfo?
var body: some View {
Map(camera: $camera, mode: .hybrid)
.onPlaceTap { tapInfo in
self.tapInfo = tapInfo
isPresented.toggle()
}
.alert(
"Place tapped - \(tapInfo?.placeId ?? "nil")",
isPresented: $isPresented,
actions: { Button("OK") {} }
)
}
}
#Preview {
PlaceTapDemo()
}
Uygulamanızı önizleme ve çalıştırma
Uygulamayı önizlemek için Önizleme bölmesini açın.
Uygulamayı çalıştırmak için GoogleMaps3DDemoApp.swift
alanına yeni bir NavigationLink
ekleyin.
...
NavigationLink(destination: PlaceTapDemo()) {
Text("Place Tap Demo")
}
...
10. (İsteğe bağlı) Daha da ileri gitme
Gelişmiş kamera animasyonları
Bazı kullanım alanları, bir sıra veya konum ya da kamera durumu listesi boyunca sorunsuz bir şekilde animasyon yapılmasını gerektirir (ör. uçuş simülatörü veya bir yürüyüşü ya da koşuyu yeniden oynatma).
Bu adımda, bir dosyadan konum listesini nasıl yükleyeceğinizi ve her konumu sırayla nasıl canlandıracağınızı öğreneceksiniz.
Bir dizi konum içeren bir dosya yükleyin.
GitHub örnek uygulama deposundan flightpath.json
dosyasını indirin.
Xcode projenizde JSON
adlı yeni bir klasör oluşturun.
flightpath.json
dosyasını Xcode'daki JSON
klasörünüze sürükleyin.
Hedefi, uygulamanızın ana hedefi olacak şekilde ayarlayın. Projenizin Paket Kaynaklarını Kopyala ayarlarının bu dosyayı içerdiğinden emin olun.
Uygulamanızda FlightPathData.swift
ve FlightDataLoader.swift
adlı iki yeni Swift dosyası oluşturun.
Aşağıdaki kodu uygulamanıza kopyalayın. Bu kod, "flighpath.json" adlı yerel bir dosyayı okuyan ve JSON olarak kodunu çözen yapıları ve sınıfları oluşturur.
FlightPathData
ve FlightPathLocation
yapıları, JSON dosyasındaki veri yapısını Swift nesneleri olarak temsil eder.
FlightDataLoader
sınıfı, dosyasındaki verileri okur ve kodlarını çözer. Uygulamanızın verilerindeki değişiklikleri gözlemlemesine izin vermek için ObservableObject
protokolünü kullanır.
Ayrıştırılan veriler, yayınlanan bir mülk aracılığıyla gösterilir.
FlightPaths.swift
import GoogleMaps3D
struct FlightPathData: Decodable {
let flight: [FlightPathLocation]
}
struct FlightPathLocation: Decodable {
let timestamp: Int64
let latitude: Double
let longitude: Double
let altitude: Double
let bearing: Double
let speed: Double
}
FlightDataLoader.swift
import Foundation
public class FlightDataLoader : ObservableObject {
@Published var flightPathData: FlightPathData = FlightPathData(flight:[])
@Published var isLoaded: Bool = false
public init() {
load("flightpath.json")
}
public func load(_ path: String) {
if let url = Bundle.main.url(forResource: path, withExtension: nil){
if let data = try? Data(contentsOf: url){
let jsondecoder = JSONDecoder()
do{
let result = try jsondecoder.decode(FlightPathData.self, from: data)
flightPathData = result
isLoaded = true
}
catch {
print("Error trying to load or parse the JSON file.")
}
}
}
}
}
Kamerayı her konumda hareket ettirin
Kamerayı bir dizi adım arasında animasyonlu olarak hareket ettirmek için KeyframeAnimator
kullanırsınız.
Her Keyframe
, CubicKeyframe
olarak oluşturulur. Böylece kamera durumundaki değişiklikler sorunsuz bir şekilde animasyonlu olarak gösterilir.
flyCameraTo()
kullanılması, görünümün her konum arasında "zıplamasına" neden olur.
Öncelikle MapHelpers.swift
içinde "innsbruck" adlı bir kamera tanımlayın.
public static var innsbruck: Camera = .init(
latitude: 47.263,
longitude: 11.3704,
altitude: 640.08,
heading: 237,
tilt: 80.0,
roll: 0.0,
range: 200)
Ardından, FlyAlongRoute.swift
adlı yeni bir dosyada yeni bir görünüm oluşturun.
SwiftUI
ve GoogleMaps3D
dosyalarını içe aktarın. Bir VStack
içine bir Map
ve bir Button
ekleyin. Boole animation
değişkeninin durumunu değiştirmek için Button
'ü ayarlayın.
FlightDataLoader
için bir State
nesnesi tanımlayın. Bu nesne, başlatılırken JSON dosyasını yükler.
import GoogleMaps3D
import SwiftUI
struct FlyAlongRoute: View {
@State private var camera: Camera = .innsbruck
@State private var flyToDuration: TimeInterval = 5
@State var animation: Bool = true
@StateObject var flightData: FlightDataLoader = FlightDataLoader()
var body: some View {
VStack {
Map(camera: $camera, mode: .hybrid)
Button("Fly Along Route"){
animation.toggle()
}
}
}
}
Animasyon karelerini oluşturma
Temel işlem, animasyon dizisinde yeni bir kare döndüren bir işlev oluşturmaktır. Her yeni kare, animatör tarafından animasyon oluşturulacak bir sonraki kamera durumunu tanımlar. Bu işlev oluşturulduktan sonra, dosyanın her bir konumunu sırayla kullanarak işlevi çağırın.
FlyAlongRoute
yapınıza iki işlev ekleyin. makeKeyFrame
işlevi, kamera durumu içeren bir CubicKeyframe
döndürür. makeCamera
işlevi, uçuş verileri dizisinde bir adım atar ve adımı temsil eden bir Camera
nesnesi döndürür.
func makeKeyFrame(step: FlightPathLocation) -> CubicKeyframe<Camera> {
return CubicKeyframe(
makeCamera(step: step),
duration: flyToDuration
)
}
func makeCamera(step: FlightPathLocation) -> Camera {
return .init(
latitude: step.latitude,
longitude: step.longitude,
altitude: step.altitude,
heading: step.bearing,
tilt: 75,
roll: 0,
range: 200
)
}
Animasyonu bir araya getirme
Map
başlatıldıktan sonra keyframeAnimator
işlevini çağırın ve ilk değerleri ayarlayın.
Uçuş yolundaki ilk konuma dayalı bir ilk kamera durumuna ihtiyacınız vardır.
Animasyon, değişkenin durumunun değişmesine göre tetiklenmelidir.
keyframeAnimator
içeriği bir Harita olmalıdır.
Ana karelerin gerçek listesi, uçuş yolundaki her konumda döngü yapılarak oluşturulur.
VStack {
Map(camera: $camera, mode: .hybrid)
.keyframeAnimator(
initialValue: makeCamera(step: flightData.flightPathData.flight[0]),
trigger: animation,
content: { view, value in
Map(camera: .constant(value), mode: .hybrid)
},
keyframes: { _ in
KeyframeTrack(content: {
for i in 1...flightData.flightPathData.flight.count-1 {
makeKeyFrame(step: flightData.flightPathData.flight[i])
}
})
}
)
}
Uygulamanızı önizleyin ve çalıştırın.
Görünümünüzü önizlemek için Önizleme bölmesini açın.
GoogleMaps3DDemoApp.swift
'ye FlightPathDemo()
hedefli yeni bir NavigationLink
ekleyin ve denemek için uygulamayı çalıştırın.
11. Tebrikler
Aşağıdakileri başarıyla yapan bir uygulama oluşturdunuz:
- Uygulamanıza temel bir 3D harita ekler.
- Haritanıza işaretçi, çizgi, poligon ve model ekler.
- Harita üzerinde ve belirli konumların etrafında uçmak için kamerayı kontrol edecek kod uygular.
Öğrendikleriniz
GoogleMaps3D
paketini Xcode SwiftUI uygulamasına ekleme.- API anahtarı ve varsayılan görünüm içeren bir 3D haritayı başlatma.
- Haritanıza işaretçi, 3D model, çizgi ve poligon ekleme.
- Kamerayı kontrol ederek başka bir konuma hareketi animasyonlu olarak gösterme
- Yer işaretçilerindeki tıklama etkinliklerini işleme
Sırada ne var?
- iOS için Haritalar 3D SDK'sı ile neler yapabileceğiniz hakkında daha fazla bilgi için geliştirici kılavuzuna göz atın.
- Aşağıdaki anketi yanıtlayarak en faydalı bulduğunuz içerikleri oluşturmamıza yardımcı olun: